@dxos/react-ui-editor 0.7.4 → 0.7.5-feature-compute.4d9d99a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +1114 -1128
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +1178 -1202
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +1114 -1128
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/InputMode.stories.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +4 -0
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/blocks.d.ts +18 -0
- package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/comment.d.ts +17 -0
- package/dist/types/src/components/EditorToolbar/comment.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/formatting.d.ts +18 -0
- package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/headings.d.ts +18 -0
- package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/index.d.ts +3 -0
- package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/lists.d.ts +18 -0
- package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/util.d.ts +58 -0
- package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/viewMode.d.ts +18 -0
- package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +3 -4
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/editorAction.d.ts +12 -0
- package/dist/types/src/extensions/markdown/editorAction.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts +14 -12
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +5 -2
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
- package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +3 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/stack-item-content-class-names.d.ts +3 -0
- package/dist/types/src/styles/stack-item-content-class-names.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +28 -27
- package/src/InputMode.stories.tsx +7 -10
- package/src/components/EditorToolbar/EditorToolbar.tsx +106 -0
- package/src/components/EditorToolbar/blocks.ts +41 -0
- package/src/components/EditorToolbar/comment.ts +20 -0
- package/src/components/EditorToolbar/formatting.ts +41 -0
- package/src/components/EditorToolbar/headings.ts +59 -0
- package/src/components/EditorToolbar/index.ts +6 -0
- package/src/components/EditorToolbar/lists.ts +40 -0
- package/src/components/EditorToolbar/util.ts +65 -0
- package/src/components/EditorToolbar/viewMode.ts +48 -0
- package/src/components/index.ts +1 -1
- package/src/extensions/comments.ts +8 -15
- package/src/extensions/markdown/{action.ts → editorAction.ts} +22 -20
- package/src/extensions/markdown/formatting.ts +20 -24
- package/src/extensions/markdown/index.ts +1 -1
- package/src/extensions/markdown/styles.ts +21 -0
- package/src/extensions/modes.ts +6 -2
- package/src/hooks/useActionHandler.ts +4 -4
- package/src/index.ts +6 -2
- package/src/styles/stack-item-content-class-names.ts +17 -0
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -34
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
- package/dist/types/src/components/Toolbar/index.d.ts +0 -2
- package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/action.d.ts +0 -9
- package/dist/types/src/extensions/markdown/action.d.ts.map +0 -1
- package/src/components/Toolbar/Toolbar.tsx +0 -522
- package/src/components/Toolbar/index.ts +0 -5
@@ -34,263 +34,861 @@ var translations_default = [
|
|
34
34
|
];
|
35
35
|
|
36
36
|
// packages/ui/react-ui-editor/src/index.ts
|
37
|
-
import {
|
37
|
+
import { EditorState as EditorState3 } from "@codemirror/state";
|
38
|
+
import { EditorView as EditorView21, keymap as keymap11 } from "@codemirror/view";
|
38
39
|
import { tags as tags2 } from "@lezer/highlight";
|
39
40
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
40
41
|
|
41
|
-
// packages/ui/react-ui-editor/src/components/
|
42
|
-
import
|
43
|
-
import {
|
44
|
-
import
|
45
|
-
import {
|
46
|
-
import { Button, DropdownMenu, ElevationProvider, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
47
|
-
import { getSize } from "@dxos/react-ui-theme";
|
42
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
43
|
+
import React, { useCallback } from "react";
|
44
|
+
import { ElevationProvider } from "@dxos/react-ui";
|
45
|
+
import { ToolbarMenu, MenuProvider, useMenuActions, createGapSeparator } from "@dxos/react-ui-menu";
|
46
|
+
import { textBlockWidth } from "@dxos/react-ui-theme";
|
48
47
|
|
49
|
-
// packages/ui/react-ui-editor/src/
|
50
|
-
import {
|
51
|
-
import {
|
52
|
-
import {
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
var
|
57
|
-
|
58
|
-
|
59
|
-
|
48
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/util.ts
|
49
|
+
import { useMemo } from "react";
|
50
|
+
import { create } from "@dxos/live-object";
|
51
|
+
import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
|
52
|
+
var useEditorToolbarState = (initialState = {}) => {
|
53
|
+
return useMemo(() => create(initialState), []);
|
54
|
+
};
|
55
|
+
var createEditorAction = (payload, icon, label = [
|
56
|
+
`${payload.type} label`,
|
57
|
+
{
|
58
|
+
ns: translationKey
|
60
59
|
}
|
60
|
+
], id = payload.type) => createMenuAction(id, {
|
61
|
+
icon,
|
62
|
+
label,
|
63
|
+
...payload
|
64
|
+
});
|
65
|
+
var createEditorActionGroup = (id, props, icon) => createMenuItemGroup(id, {
|
66
|
+
icon,
|
67
|
+
iconOnly: true,
|
68
|
+
...props
|
61
69
|
});
|
70
|
+
var editorToolbarSearch = createEditorAction({
|
71
|
+
type: "search"
|
72
|
+
}, "ph--magnifying-glass--regular");
|
62
73
|
|
63
|
-
// packages/ui/react-ui-editor/src/
|
64
|
-
var
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
};
|
69
|
-
var
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
74
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/blocks.ts
|
75
|
+
var createBlockGroupAction = (value) => createEditorActionGroup("block", {
|
76
|
+
variant: "toggleGroup",
|
77
|
+
selectCardinality: "single",
|
78
|
+
value
|
79
|
+
});
|
80
|
+
var createBlockActions = (value, blankLine) => Object.entries({
|
81
|
+
blockquote: "ph--quotes--regular",
|
82
|
+
codeblock: "ph--code-block--regular",
|
83
|
+
table: "ph--table--regular"
|
84
|
+
}).map(([type, icon]) => {
|
85
|
+
return createEditorAction({
|
86
|
+
type,
|
87
|
+
checked: type === value,
|
88
|
+
...type === "table" && {
|
89
|
+
disabled: !!blankLine
|
90
|
+
}
|
91
|
+
}, icon);
|
92
|
+
});
|
93
|
+
var createBlocks = (state) => {
|
94
|
+
const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
|
95
|
+
const blockGroupAction = createBlockGroupAction(value);
|
96
|
+
const blockActions = createBlockActions(value, state.blankLine);
|
97
|
+
return {
|
98
|
+
nodes: [
|
99
|
+
blockGroupAction,
|
100
|
+
...blockActions
|
101
|
+
],
|
102
|
+
edges: [
|
103
|
+
{
|
104
|
+
source: "root",
|
105
|
+
target: "block"
|
106
|
+
},
|
107
|
+
...blockActions.map(({ id }) => ({
|
108
|
+
source: blockGroupAction.id,
|
109
|
+
target: id
|
110
|
+
}))
|
111
|
+
]
|
112
|
+
};
|
96
113
|
};
|
97
114
|
|
98
|
-
// packages/ui/react-ui-editor/src/
|
99
|
-
|
100
|
-
var
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
115
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/comment.ts
|
116
|
+
var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
|
117
|
+
var createCommentAction = (label) => createEditorAction({
|
118
|
+
type: "comment",
|
119
|
+
testId: "editor.toolbar.comment"
|
120
|
+
}, "ph--chat-text--regular", label);
|
121
|
+
var createComment = (state) => ({
|
122
|
+
nodes: [
|
123
|
+
createCommentAction(commentLabel(state.comment, state.selection))
|
124
|
+
],
|
125
|
+
edges: [
|
126
|
+
{
|
127
|
+
source: "root",
|
128
|
+
target: "comment"
|
112
129
|
}
|
130
|
+
]
|
131
|
+
});
|
132
|
+
|
133
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/formatting.ts
|
134
|
+
var formats = {
|
135
|
+
strong: "ph--text-b--regular",
|
136
|
+
emphasis: "ph--text-italic--regular",
|
137
|
+
strikethrough: "ph--text-strikethrough--regular",
|
138
|
+
code: "ph--code--regular",
|
139
|
+
link: "ph--link--regular"
|
140
|
+
};
|
141
|
+
var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
|
142
|
+
variant: "toggleGroup",
|
143
|
+
selectCardinality: "multiple",
|
144
|
+
value: Object.keys(formats).filter((key) => !!formatting[key])
|
145
|
+
});
|
146
|
+
var createFormattingActions = (formatting) => Object.entries(formats).map(([type, icon]) => createEditorAction({
|
147
|
+
type,
|
148
|
+
checked: !!formatting[type]
|
149
|
+
}, icon));
|
150
|
+
var createFormatting = (state) => {
|
151
|
+
const formattingGroupAction = createFormattingGroup(state);
|
152
|
+
const formattingActions = createFormattingActions(state);
|
153
|
+
return {
|
154
|
+
nodes: [
|
155
|
+
formattingGroupAction,
|
156
|
+
...formattingActions
|
157
|
+
],
|
158
|
+
edges: [
|
159
|
+
{
|
160
|
+
source: "root",
|
161
|
+
target: "formatting"
|
162
|
+
},
|
163
|
+
...formattingActions.map(({ id }) => ({
|
164
|
+
source: formattingGroupAction.id,
|
165
|
+
target: id
|
166
|
+
}))
|
167
|
+
]
|
113
168
|
};
|
114
169
|
};
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
170
|
+
|
171
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/headings.ts
|
172
|
+
var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
|
173
|
+
variant: "dropdownMenu",
|
174
|
+
applyActive: true,
|
175
|
+
selectCardinality: "single",
|
176
|
+
value
|
177
|
+
}, "ph--text-h--regular");
|
178
|
+
var createHeadingActions = (value) => Object.entries({
|
179
|
+
"0": "ph--paragraph--regular",
|
180
|
+
"1": "ph--text-h-one--regular",
|
181
|
+
"2": "ph--text-h-two--regular",
|
182
|
+
"3": "ph--text-h-three--regular",
|
183
|
+
"4": "ph--text-h-four--regular",
|
184
|
+
"5": "ph--text-h-five--regular",
|
185
|
+
"6": "ph--text-h-six--regular"
|
186
|
+
}).map(([levelStr, icon]) => {
|
187
|
+
const level = parseInt(levelStr);
|
188
|
+
return createEditorAction({
|
189
|
+
type: "heading",
|
190
|
+
data: level,
|
191
|
+
checked: value === levelStr
|
192
|
+
}, icon, [
|
193
|
+
"heading level label",
|
194
|
+
{
|
195
|
+
count: level,
|
196
|
+
ns: translationKey
|
197
|
+
}
|
198
|
+
], `heading--${levelStr}`);
|
199
|
+
});
|
200
|
+
var computeHeadingValue = (state) => {
|
201
|
+
const blockType = state ? state.blockType : "paragraph";
|
202
|
+
const header = blockType && /heading(\d)/.exec(blockType);
|
203
|
+
return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
|
126
204
|
};
|
127
|
-
var
|
128
|
-
|
129
|
-
|
205
|
+
var createHeadings = (state) => {
|
206
|
+
const headingValue = computeHeadingValue(state);
|
207
|
+
const headingGroupAction = createHeadingGroupAction(headingValue);
|
208
|
+
const headingActions = createHeadingActions(headingValue);
|
209
|
+
return {
|
210
|
+
nodes: [
|
211
|
+
headingGroupAction,
|
212
|
+
...headingActions
|
213
|
+
],
|
214
|
+
edges: [
|
215
|
+
{
|
216
|
+
source: "root",
|
217
|
+
target: "heading"
|
218
|
+
},
|
219
|
+
...headingActions.map(({ id }) => ({
|
220
|
+
source: headingGroupAction.id,
|
221
|
+
target: id
|
222
|
+
}))
|
223
|
+
]
|
224
|
+
};
|
130
225
|
};
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
226
|
+
|
227
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/lists.ts
|
228
|
+
var listStyles = {
|
229
|
+
bullet: "ph--list-bullets--regular",
|
230
|
+
ordered: "ph--list-numbers--regular",
|
231
|
+
task: "ph--list-checks--regular"
|
232
|
+
};
|
233
|
+
var createListGroupAction = (value) => createEditorActionGroup("list", {
|
234
|
+
variant: "toggleGroup",
|
235
|
+
selectCardinality: "single",
|
236
|
+
value
|
237
|
+
});
|
238
|
+
var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
|
239
|
+
type: `list-${listStyle}`,
|
240
|
+
checked: value === listStyle
|
241
|
+
}, icon));
|
242
|
+
var createLists = (state) => {
|
243
|
+
const value = state.listStyle ?? "";
|
244
|
+
const listGroupAction = createListGroupAction(value);
|
245
|
+
const listActionsMap = createListActions(value);
|
246
|
+
return {
|
247
|
+
nodes: [
|
248
|
+
listGroupAction,
|
249
|
+
...listActionsMap
|
250
|
+
],
|
251
|
+
edges: [
|
252
|
+
{
|
253
|
+
source: "root",
|
254
|
+
target: "list"
|
255
|
+
},
|
256
|
+
...listActionsMap.map(({ id }) => ({
|
257
|
+
source: listGroupAction.id,
|
258
|
+
target: id
|
259
|
+
}))
|
260
|
+
]
|
261
|
+
};
|
262
|
+
};
|
263
|
+
|
264
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/viewMode.ts
|
265
|
+
var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
|
266
|
+
variant: "dropdownMenu",
|
267
|
+
applyActive: true,
|
268
|
+
selectCardinality: "single",
|
269
|
+
value
|
270
|
+
}, "ph--eye--regular");
|
271
|
+
var createViewModeActions = (value) => Object.entries({
|
272
|
+
preview: "ph--eye--regular",
|
273
|
+
source: "ph--pencil-simple--regular",
|
274
|
+
readonly: "ph--pencil-slash--regular"
|
275
|
+
}).map(([viewMode, icon]) => {
|
276
|
+
return createEditorAction({
|
277
|
+
type: "view-mode",
|
278
|
+
data: viewMode,
|
279
|
+
checked: viewMode === value
|
280
|
+
}, icon, [
|
281
|
+
`${viewMode} mode label`,
|
282
|
+
{
|
283
|
+
ns: translationKey
|
135
284
|
}
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
285
|
+
], `view-mode--${viewMode}`);
|
286
|
+
});
|
287
|
+
var createViewMode = (state) => {
|
288
|
+
const value = state.viewMode ?? "source";
|
289
|
+
const viewModeGroupAction = createViewModeGroupAction(value);
|
290
|
+
const viewModeActions = createViewModeActions(value);
|
291
|
+
return {
|
292
|
+
nodes: [
|
293
|
+
viewModeGroupAction,
|
294
|
+
...viewModeActions
|
295
|
+
],
|
296
|
+
edges: [
|
297
|
+
{
|
298
|
+
source: "root",
|
299
|
+
target: "viewMode"
|
300
|
+
},
|
301
|
+
...viewModeActions.map(({ id }) => ({
|
302
|
+
source: viewModeGroupAction.id,
|
303
|
+
target: id
|
304
|
+
}))
|
305
|
+
]
|
306
|
+
};
|
156
307
|
};
|
157
308
|
|
158
|
-
// packages/ui/react-ui-editor/src/
|
159
|
-
|
160
|
-
|
309
|
+
// packages/ui/react-ui-editor/src/styles/stack-item-content-class-names.ts
|
310
|
+
import { mx } from "@dxos/react-ui-theme";
|
311
|
+
var stackItemContentEditorClassNames = (role) => mx("ch-focus-ring-inset data-[toolbar=disabled]:pbs-2 attention-surface", role === "article" ? "min-bs-0" : "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24");
|
312
|
+
var stackItemContentToolbarClassNames = (role) => mx("attention-surface is-full border-be !border-separator", role === "section" && "sticky block-start-0 z-[1] -mbe-px min-is-0");
|
313
|
+
|
314
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
315
|
+
var createToolbar = ({ state, customActions, ...features }) => {
|
316
|
+
const nodes = [];
|
317
|
+
const edges = [];
|
318
|
+
if (features.headings ?? true) {
|
319
|
+
const headings2 = createHeadings(state);
|
320
|
+
nodes.push(...headings2.nodes);
|
321
|
+
edges.push(...headings2.edges);
|
322
|
+
}
|
323
|
+
if (features.formatting ?? true) {
|
324
|
+
const formatting = createFormatting(state);
|
325
|
+
nodes.push(...formatting.nodes);
|
326
|
+
edges.push(...formatting.edges);
|
327
|
+
}
|
328
|
+
if (features.lists ?? true) {
|
329
|
+
const lists = createLists(state);
|
330
|
+
nodes.push(...lists.nodes);
|
331
|
+
edges.push(...lists.edges);
|
332
|
+
}
|
333
|
+
if (features.blocks ?? true) {
|
334
|
+
const blocks = createBlocks(state);
|
335
|
+
nodes.push(...blocks.nodes);
|
336
|
+
edges.push(...blocks.edges);
|
337
|
+
}
|
338
|
+
if (customActions) {
|
339
|
+
const custom = customActions();
|
340
|
+
nodes.push(...custom.nodes);
|
341
|
+
edges.push(...custom.edges);
|
342
|
+
}
|
343
|
+
const editorToolbarGap = createGapSeparator();
|
344
|
+
nodes.push(...editorToolbarGap.nodes);
|
345
|
+
edges.push(...editorToolbarGap.edges);
|
346
|
+
if (features.comment ?? true) {
|
347
|
+
const comment = createComment(state);
|
348
|
+
nodes.push(...comment.nodes);
|
349
|
+
edges.push(...comment.edges);
|
350
|
+
}
|
351
|
+
if (features.search ?? true) {
|
352
|
+
nodes.push(editorToolbarSearch);
|
353
|
+
edges.push({
|
354
|
+
source: "root",
|
355
|
+
target: editorToolbarSearch.id
|
356
|
+
});
|
357
|
+
}
|
358
|
+
if (features.viewMode ?? true) {
|
359
|
+
const viewMode = createViewMode(state);
|
360
|
+
nodes.push(...viewMode.nodes);
|
361
|
+
edges.push(...viewMode.edges);
|
362
|
+
}
|
161
363
|
return {
|
162
|
-
|
163
|
-
|
164
|
-
top: rect.top,
|
165
|
-
bottom: rect.bottom
|
364
|
+
nodes,
|
365
|
+
edges
|
166
366
|
};
|
167
367
|
};
|
168
|
-
var
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
return
|
368
|
+
var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
|
369
|
+
const menuCreator = useCallback(() => createToolbar(props), [
|
370
|
+
props
|
371
|
+
]);
|
372
|
+
const { resolveGroupItems } = useMenuActions(menuCreator);
|
373
|
+
return {
|
374
|
+
resolveGroupItems,
|
375
|
+
onAction
|
376
|
+
};
|
174
377
|
};
|
175
|
-
var
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
}
|
181
|
-
|
182
|
-
}
|
378
|
+
var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
|
379
|
+
const menuProps = useEditorToolbarActionGraph(props);
|
380
|
+
return /* @__PURE__ */ React.createElement("div", {
|
381
|
+
role: "none",
|
382
|
+
className: stackItemContentToolbarClassNames(role)
|
383
|
+
}, /* @__PURE__ */ React.createElement(ElevationProvider, {
|
384
|
+
elevation: role === "section" ? "positioned" : "base"
|
385
|
+
}, /* @__PURE__ */ React.createElement(MenuProvider, {
|
386
|
+
...menuProps,
|
387
|
+
attendableId
|
388
|
+
}, /* @__PURE__ */ React.createElement(ToolbarMenu, {
|
389
|
+
classNames: [
|
390
|
+
textBlockWidth,
|
391
|
+
"!bg-transparent",
|
392
|
+
classNames
|
393
|
+
]
|
394
|
+
}))));
|
183
395
|
};
|
184
396
|
|
185
|
-
// packages/ui/react-ui-editor/src/
|
186
|
-
import
|
187
|
-
import {
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
397
|
+
// packages/ui/react-ui-editor/src/defaults.ts
|
398
|
+
import { EditorView } from "@codemirror/view";
|
399
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
400
|
+
|
401
|
+
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
402
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
403
|
+
var headings = {
|
404
|
+
1: "text-4xl",
|
405
|
+
2: "text-3xl",
|
406
|
+
3: "text-2xl",
|
407
|
+
4: "text-xl",
|
408
|
+
5: "text-lg",
|
409
|
+
6: "text-md"
|
410
|
+
};
|
411
|
+
var theme = {
|
412
|
+
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
413
|
+
codeMark: "font-mono text-primary-500",
|
414
|
+
mark: "opacity-50",
|
415
|
+
heading: (level) => {
|
416
|
+
return mx2(headings[level], "dark:text-primary-400");
|
199
417
|
}
|
200
|
-
return el;
|
201
418
|
};
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
419
|
+
|
420
|
+
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
421
|
+
import get from "lodash.get";
|
422
|
+
import { tokens } from "@dxos/react-ui-theme";
|
423
|
+
var getToken = (path, defaultValue) => {
|
424
|
+
const value = get(tokens, path, defaultValue);
|
425
|
+
return value?.toString() ?? "";
|
207
426
|
};
|
427
|
+
var fontBody = getToken("fontFamily.body");
|
428
|
+
var fontMono = getToken("fontFamily.mono");
|
208
429
|
|
209
|
-
// packages/ui/react-ui-editor/src/
|
210
|
-
var
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
}
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
430
|
+
// packages/ui/react-ui-editor/src/styles/theme.ts
|
431
|
+
var defaultTheme = {
|
432
|
+
"&": {},
|
433
|
+
"&.cm-focused": {
|
434
|
+
outline: "none"
|
435
|
+
},
|
436
|
+
/**
|
437
|
+
* Scroller
|
438
|
+
*/
|
439
|
+
".cm-scroller": {
|
440
|
+
overflowY: "auto"
|
441
|
+
},
|
442
|
+
/**
|
443
|
+
* Content
|
444
|
+
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
445
|
+
*/
|
446
|
+
".cm-content": {
|
447
|
+
padding: "unset",
|
448
|
+
fontFamily: fontBody,
|
449
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
450
|
+
fontSize: "16px",
|
451
|
+
lineHeight: 1.5,
|
452
|
+
color: "unset"
|
453
|
+
},
|
454
|
+
/**
|
455
|
+
* Gutters
|
456
|
+
* NOTE: Gutters should have the same top margin as the content.
|
457
|
+
* NOTE: They can't be transparent since the content needs to scroll below.
|
458
|
+
*/
|
459
|
+
".cm-gutters": {
|
460
|
+
background: "var(--surface-bg)",
|
461
|
+
borderRight: "none"
|
462
|
+
},
|
463
|
+
".cm-gutter": {},
|
464
|
+
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
465
|
+
minWidth: "40px",
|
466
|
+
alignContent: "center"
|
467
|
+
},
|
468
|
+
/**
|
469
|
+
* Height is set to match the corresponding line.
|
470
|
+
*/
|
471
|
+
".cm-gutterElement": {
|
472
|
+
alignItems: "center",
|
473
|
+
fontSize: "16px"
|
474
|
+
},
|
475
|
+
/**
|
476
|
+
* Line.
|
477
|
+
*/
|
478
|
+
".cm-line": {
|
479
|
+
paddingInline: 0
|
480
|
+
},
|
481
|
+
".cm-activeLine": {
|
482
|
+
background: "var(--dx-cmActiveLine)"
|
483
|
+
},
|
484
|
+
/**
|
485
|
+
* Cursor (layer).
|
486
|
+
*/
|
487
|
+
".cm-cursor, .cm-dropCursor": {
|
488
|
+
borderLeft: "2px solid var(--dx-cmCursor)"
|
489
|
+
},
|
490
|
+
".cm-placeholder": {
|
491
|
+
color: "var(--dx-subdued)"
|
492
|
+
},
|
493
|
+
/**
|
494
|
+
* Selection (layer).
|
495
|
+
*/
|
496
|
+
".cm-selectionBackground": {
|
497
|
+
background: "var(--dx-cmSelection)"
|
498
|
+
},
|
499
|
+
/**
|
500
|
+
* Search.
|
501
|
+
* NOTE: Matches comment.
|
502
|
+
*/
|
503
|
+
".cm-searchMatch": {
|
504
|
+
margin: "0 -3px",
|
505
|
+
padding: "3px",
|
506
|
+
borderRadius: "3px",
|
507
|
+
background: "var(--dx-cmHighlightSurface)",
|
508
|
+
color: "var(--dx-cmHighlight)"
|
509
|
+
},
|
510
|
+
".cm-searchMatch-selected": {
|
511
|
+
textDecoration: "underline"
|
512
|
+
},
|
513
|
+
/**
|
514
|
+
* Link.
|
515
|
+
*/
|
516
|
+
".cm-link": {
|
517
|
+
textDecorationLine: "underline",
|
518
|
+
textDecorationThickness: "1px",
|
519
|
+
textUnderlineOffset: "2px",
|
520
|
+
borderRadius: ".125rem"
|
521
|
+
},
|
522
|
+
".cm-link > span": {
|
523
|
+
color: "var(--dx-accentText)"
|
524
|
+
},
|
525
|
+
/**
|
526
|
+
* Tooltip.
|
527
|
+
*/
|
528
|
+
".cm-tooltip": {
|
529
|
+
background: "var(--dx-base)"
|
530
|
+
},
|
531
|
+
".cm-tooltip-below": {},
|
532
|
+
/**
|
533
|
+
* Autocomplete.
|
534
|
+
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
535
|
+
*/
|
536
|
+
".cm-tooltip.cm-tooltip-autocomplete": {
|
537
|
+
marginTop: "4px",
|
538
|
+
marginLeft: "-3px"
|
539
|
+
},
|
540
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
541
|
+
maxHeight: "20em"
|
542
|
+
},
|
543
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
544
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
545
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
546
|
+
paddingLeft: "4px !important",
|
547
|
+
borderBottom: "none !important",
|
548
|
+
color: "var(--dx-accentText)"
|
549
|
+
},
|
550
|
+
".cm-tooltip.cm-completionInfo": {
|
551
|
+
width: "360px !important",
|
552
|
+
margin: "-10px 1px 0 1px",
|
553
|
+
padding: "8px !important",
|
554
|
+
borderColor: "var(--dx-separator)"
|
555
|
+
},
|
556
|
+
".cm-completionIcon": {
|
557
|
+
display: "none"
|
558
|
+
},
|
559
|
+
".cm-completionLabel": {
|
560
|
+
fontFamily: fontBody
|
561
|
+
},
|
562
|
+
".cm-completionMatchedText": {
|
563
|
+
textDecoration: "none !important",
|
564
|
+
opacity: 0.5
|
565
|
+
},
|
566
|
+
/**
|
567
|
+
* Panels
|
568
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
569
|
+
*
|
570
|
+
* Find/replace panel.
|
571
|
+
* <div class="cm-announced">...</div>
|
572
|
+
* <div class="cm-scroller">...</div>
|
573
|
+
* <div class="cm-panels cm-panels-bottom">
|
574
|
+
* <div class="cm-search cm-panel">
|
575
|
+
* <input class="cm-textfield" />
|
576
|
+
* <button class="cm-button">...</button>
|
577
|
+
* <label><input type="checkbox" />...</label>
|
578
|
+
* </div>
|
579
|
+
* </div
|
580
|
+
*/
|
581
|
+
// TODO(burdon): Implement custom panel (with icon buttons).
|
582
|
+
".cm-panels": {},
|
583
|
+
".cm-panel": {
|
584
|
+
fontFamily: fontBody,
|
585
|
+
backgroundColor: "var(--surface-bg)"
|
586
|
+
},
|
587
|
+
".cm-panel input, .cm-panel button, .cm-panel label": {
|
588
|
+
color: "var(--dx-subdued)",
|
589
|
+
fontFamily: fontBody,
|
590
|
+
fontSize: "14px",
|
591
|
+
all: "unset",
|
592
|
+
margin: "3px !important",
|
593
|
+
padding: "2px 6px !important",
|
594
|
+
outline: "1px solid transparent"
|
595
|
+
},
|
596
|
+
".cm-panel input, .cm-panel button": {
|
597
|
+
backgroundColor: "var(--dx-input)"
|
598
|
+
},
|
599
|
+
".cm-panel input:focus, .cm-panel button:focus": {
|
600
|
+
outline: "1px solid var(--dx-accentFocusIndicator)"
|
601
|
+
},
|
602
|
+
".cm-panel label": {
|
603
|
+
display: "inline-flex",
|
604
|
+
alignItems: "center",
|
605
|
+
cursor: "pointer"
|
606
|
+
},
|
607
|
+
".cm-panel input.cm-textfield": {},
|
608
|
+
".cm-panel input[type=checkbox]": {
|
609
|
+
width: "8px",
|
610
|
+
height: "8px",
|
611
|
+
marginRight: "6px !important",
|
612
|
+
padding: "2px !important",
|
613
|
+
color: "var(--dx-accentFocusIndicator)"
|
614
|
+
},
|
615
|
+
".cm-panel button": {
|
616
|
+
"&:hover": {
|
617
|
+
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
618
|
+
},
|
619
|
+
"&:active": {
|
620
|
+
backgroundColor: "var(--dx-accentSurfaceHover)"
|
242
621
|
}
|
243
|
-
}
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
], (state) => {
|
249
|
-
const annotations2 = state.field(annotationsState);
|
250
|
-
const decorations = annotations2.map((annotation) => {
|
251
|
-
const range = Cursor.getRangeFromCursor(state, annotation.cursor);
|
252
|
-
return range && annotationMark.range(range.from, range.to);
|
253
|
-
}).filter(isNotFalsy);
|
254
|
-
return Decoration.set(decorations);
|
255
|
-
}),
|
256
|
-
styles
|
257
|
-
];
|
622
|
+
},
|
623
|
+
".cm-panel.cm-search": {
|
624
|
+
padding: "4px",
|
625
|
+
borderTop: "1px solid var(--dx-separator)"
|
626
|
+
}
|
258
627
|
};
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
628
|
+
|
629
|
+
// packages/ui/react-ui-editor/src/defaults.ts
|
630
|
+
var margin = "!mt-[1rem]";
|
631
|
+
var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
|
632
|
+
var editorFullWidth = mx3(margin);
|
633
|
+
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
634
|
+
var editorGutter = EditorView.theme({
|
635
|
+
// Match margin from content.
|
636
|
+
".cm-gutters": {
|
637
|
+
marginTop: "16px",
|
638
|
+
paddingRight: "1rem"
|
639
|
+
}
|
640
|
+
});
|
641
|
+
var editorMonospace = EditorView.theme({
|
642
|
+
".cm-content": {
|
643
|
+
fontFamily: fontMono
|
264
644
|
}
|
265
645
|
});
|
266
646
|
|
267
|
-
// packages/ui/react-ui-editor/src/extensions/
|
268
|
-
import {
|
269
|
-
import {
|
270
|
-
import {
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
647
|
+
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
648
|
+
import { StateField } from "@codemirror/state";
|
649
|
+
import { Decoration, EditorView as EditorView2 } from "@codemirror/view";
|
650
|
+
import { isNotFalsy } from "@dxos/util";
|
651
|
+
|
652
|
+
// packages/ui/react-ui-editor/src/util/facet.ts
|
653
|
+
import { Facet } from "@codemirror/state";
|
654
|
+
var singleValueFacet = (defaultValue) => Facet.define({
|
655
|
+
// Called immediately.
|
656
|
+
combine: (providers) => {
|
657
|
+
return providers[0] ?? defaultValue;
|
658
|
+
}
|
659
|
+
});
|
660
|
+
|
661
|
+
// packages/ui/react-ui-editor/src/util/cursor.ts
|
662
|
+
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
663
|
+
var defaultCursorConverter = {
|
664
|
+
toCursor: (position) => position.toString(),
|
665
|
+
fromCursor: (cursor) => parseInt(cursor)
|
666
|
+
};
|
667
|
+
var Cursor = class _Cursor {
|
668
|
+
static {
|
669
|
+
this.converter = singleValueFacet(defaultCursorConverter);
|
670
|
+
}
|
671
|
+
static {
|
672
|
+
this.getCursorFromRange = (state, range) => {
|
673
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
674
|
+
const from = cursorConverter2.toCursor(range.from);
|
675
|
+
const to = cursorConverter2.toCursor(range.to, -1);
|
676
|
+
return [
|
677
|
+
from,
|
678
|
+
to
|
679
|
+
].join(":");
|
680
|
+
};
|
681
|
+
}
|
682
|
+
static {
|
683
|
+
this.getRangeFromCursor = (state, cursor) => {
|
684
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
685
|
+
const parts = cursor.split(":");
|
686
|
+
const from = cursorConverter2.fromCursor(parts[0]);
|
687
|
+
const to = cursorConverter2.fromCursor(parts[1]);
|
688
|
+
return from !== void 0 && to !== void 0 ? {
|
689
|
+
from,
|
690
|
+
to
|
691
|
+
} : void 0;
|
692
|
+
};
|
693
|
+
}
|
694
|
+
};
|
695
|
+
|
696
|
+
// packages/ui/react-ui-editor/src/util/debug.ts
|
697
|
+
import { log } from "@dxos/log";
|
698
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
|
699
|
+
var wrapWithCatch = (fn) => {
|
700
|
+
return (...args) => {
|
701
|
+
try {
|
702
|
+
return fn(...args);
|
703
|
+
} catch (err) {
|
704
|
+
log.catch(err, void 0, {
|
705
|
+
F: __dxlog_file,
|
706
|
+
L: 15,
|
707
|
+
S: void 0,
|
708
|
+
C: (f, a) => f(...a)
|
709
|
+
});
|
710
|
+
}
|
711
|
+
};
|
712
|
+
};
|
713
|
+
var callbackWrapper = (fn) => (...args) => {
|
714
|
+
try {
|
715
|
+
return fn(...args);
|
716
|
+
} catch (err) {
|
717
|
+
log.catch(err, void 0, {
|
718
|
+
F: __dxlog_file,
|
719
|
+
L: 29,
|
720
|
+
S: void 0,
|
721
|
+
C: (f, a) => f(...a)
|
722
|
+
});
|
723
|
+
}
|
724
|
+
};
|
725
|
+
var debugDispatcher = (trs, view) => {
|
726
|
+
logChanges(trs);
|
727
|
+
view.update(trs);
|
728
|
+
};
|
729
|
+
var logChanges = (trs) => {
|
730
|
+
const changes = trs.flatMap((tr) => {
|
731
|
+
if (tr.changes.empty) {
|
732
|
+
return void 0;
|
733
|
+
}
|
734
|
+
const changes2 = [];
|
735
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
|
736
|
+
fromA,
|
737
|
+
toA,
|
738
|
+
fromB,
|
739
|
+
toB,
|
740
|
+
inserted: inserted.toString()
|
741
|
+
})));
|
742
|
+
return changes2;
|
743
|
+
}).filter(Boolean);
|
744
|
+
if (changes.length) {
|
745
|
+
log.info("changes", {
|
746
|
+
changes
|
747
|
+
}, {
|
748
|
+
F: __dxlog_file,
|
749
|
+
L: 62,
|
750
|
+
S: void 0,
|
751
|
+
C: (f, a) => f(...a)
|
752
|
+
});
|
753
|
+
}
|
754
|
+
};
|
755
|
+
|
756
|
+
// packages/ui/react-ui-editor/src/util/dom.ts
|
757
|
+
var flattenRect = (rect, left) => {
|
758
|
+
const x = left ? rect.left : rect.right;
|
759
|
+
return {
|
760
|
+
left: x,
|
761
|
+
right: x,
|
762
|
+
top: rect.top,
|
763
|
+
bottom: rect.bottom
|
764
|
+
};
|
765
|
+
};
|
766
|
+
var scratchRange;
|
767
|
+
var textRange = (node, from, to = from) => {
|
768
|
+
const range = scratchRange || (scratchRange = document.createRange());
|
769
|
+
range.setEnd(node, to);
|
770
|
+
range.setStart(node, from);
|
771
|
+
return range;
|
772
|
+
};
|
773
|
+
var clientRectsFor = (dom) => {
|
774
|
+
if (dom.nodeType === 3) {
|
775
|
+
return textRange(dom, 0, dom.nodeValue.length).getClientRects();
|
776
|
+
} else if (dom.nodeType === 1) {
|
777
|
+
return dom.getClientRects();
|
778
|
+
} else {
|
779
|
+
return [];
|
780
|
+
}
|
781
|
+
};
|
782
|
+
|
783
|
+
// packages/ui/react-ui-editor/src/util/react.tsx
|
784
|
+
import React2 from "react";
|
785
|
+
import { createRoot } from "react-dom/client";
|
786
|
+
import { ThemeProvider } from "@dxos/react-ui";
|
787
|
+
import { defaultTx } from "@dxos/react-ui-theme";
|
788
|
+
var createElement = (tag, options, children) => {
|
789
|
+
const el = document.createElement(tag);
|
790
|
+
if (options?.className) {
|
791
|
+
el.className = options.className;
|
792
|
+
}
|
793
|
+
if (children) {
|
794
|
+
el.append(...Array.isArray(children) ? children : [
|
795
|
+
children
|
796
|
+
]);
|
797
|
+
}
|
798
|
+
return el;
|
799
|
+
};
|
800
|
+
var renderRoot = (root, node) => {
|
801
|
+
createRoot(root).render(/* @__PURE__ */ React2.createElement(ThemeProvider, {
|
802
|
+
tx: defaultTx
|
803
|
+
}, node));
|
804
|
+
return root;
|
805
|
+
};
|
806
|
+
|
807
|
+
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
808
|
+
var annotationMark = Decoration.mark({
|
809
|
+
class: "cm-annotation"
|
810
|
+
});
|
811
|
+
var annotations = (options = {}) => {
|
812
|
+
const match = (state) => {
|
813
|
+
const annotations2 = [];
|
814
|
+
const text = state.doc.toString();
|
815
|
+
if (options.match) {
|
816
|
+
const matches = text.matchAll(options.match);
|
817
|
+
for (const match2 of matches) {
|
818
|
+
const from = match2.index;
|
819
|
+
const to = from + match2[0].length;
|
820
|
+
const cursor = Cursor.getCursorFromRange(state, {
|
821
|
+
from,
|
822
|
+
to
|
823
|
+
});
|
824
|
+
annotations2.push({
|
825
|
+
cursor
|
826
|
+
});
|
827
|
+
}
|
828
|
+
}
|
829
|
+
return annotations2;
|
830
|
+
};
|
831
|
+
const annotationsState = StateField.define({
|
832
|
+
create: (state) => {
|
833
|
+
return match(state);
|
834
|
+
},
|
835
|
+
update: (value, tr) => {
|
836
|
+
if (!tr.changes.empty) {
|
837
|
+
return match(tr.state);
|
838
|
+
}
|
839
|
+
return value;
|
840
|
+
}
|
841
|
+
});
|
842
|
+
return [
|
843
|
+
annotationsState,
|
844
|
+
EditorView2.decorations.compute([
|
845
|
+
annotationsState
|
846
|
+
], (state) => {
|
847
|
+
const annotations2 = state.field(annotationsState);
|
848
|
+
const decorations = annotations2.map((annotation) => {
|
849
|
+
const range = Cursor.getRangeFromCursor(state, annotation.cursor);
|
850
|
+
return range && annotationMark.range(range.from, range.to);
|
851
|
+
}).filter(isNotFalsy);
|
852
|
+
return Decoration.set(decorations);
|
853
|
+
}),
|
854
|
+
styles
|
855
|
+
];
|
856
|
+
};
|
857
|
+
var styles = EditorView2.theme({
|
858
|
+
".cm-annotation": {
|
859
|
+
textDecoration: "underline",
|
860
|
+
textDecorationStyle: "wavy",
|
861
|
+
textDecorationColor: "var(--dx-error)"
|
862
|
+
}
|
863
|
+
});
|
864
|
+
|
865
|
+
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
866
|
+
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
867
|
+
import { markdownLanguage } from "@codemirror/lang-markdown";
|
868
|
+
import { keymap } from "@codemirror/view";
|
869
|
+
var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
|
870
|
+
const extensions = [
|
871
|
+
// https://codemirror.net/docs/ref/#view.keymap
|
872
|
+
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
873
|
+
// TODO(burdon): Set custom keymap.
|
874
|
+
keymap.of(completionKeymap),
|
875
|
+
// https://codemirror.net/examples/autocompletion
|
876
|
+
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
877
|
+
autocompletion({
|
878
|
+
activateOnTyping,
|
879
|
+
override,
|
880
|
+
closeOnBlur: !debug,
|
881
|
+
tooltipClass: () => "shadow rounded"
|
882
|
+
})
|
883
|
+
];
|
884
|
+
if (onSearch) {
|
885
|
+
extensions.push(
|
886
|
+
// TODO(burdon): Optional decoration via addToOptions
|
887
|
+
markdownLanguage.data.of({
|
888
|
+
autocomplete: (context) => {
|
889
|
+
const match = context.matchBefore(/\w*/);
|
890
|
+
if (!match || match.from === match.to && !context.explicit) {
|
891
|
+
return null;
|
294
892
|
}
|
295
893
|
return {
|
296
894
|
from: match.from,
|
@@ -305,7 +903,7 @@ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
|
|
305
903
|
|
306
904
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
307
905
|
import { StateField as StateField2 } from "@codemirror/state";
|
308
|
-
import { EditorView as
|
906
|
+
import { EditorView as EditorView3, ViewPlugin } from "@codemirror/view";
|
309
907
|
import { next as A3 } from "@dxos/automerge/automerge";
|
310
908
|
|
311
909
|
// packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
|
@@ -589,7 +1187,7 @@ var automerge = (accessor) => {
|
|
589
1187
|
}
|
590
1188
|
}),
|
591
1189
|
// Reconcile local updates.
|
592
|
-
|
1190
|
+
EditorView3.updateListener.of(({ view, changes }) => {
|
593
1191
|
if (!changes.empty) {
|
594
1192
|
syncer.reconcile(view, true);
|
595
1193
|
}
|
@@ -599,7 +1197,7 @@ var automerge = (accessor) => {
|
|
599
1197
|
|
600
1198
|
// packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts
|
601
1199
|
import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
602
|
-
import { Decoration as Decoration2, EditorView as
|
1200
|
+
import { Decoration as Decoration2, EditorView as EditorView4, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
|
603
1201
|
import { Event } from "@dxos/async";
|
604
1202
|
import { Context } from "@dxos/context";
|
605
1203
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
|
@@ -773,7 +1371,7 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
773
1371
|
return true;
|
774
1372
|
}
|
775
1373
|
};
|
776
|
-
var styles2 =
|
1374
|
+
var styles2 = EditorView4.theme({
|
777
1375
|
".cm-collab-selection": {},
|
778
1376
|
".cm-collab-selectionLine": {
|
779
1377
|
padding: 0,
|
@@ -939,7 +1537,7 @@ var SpaceAwarenessProvider = class {
|
|
939
1537
|
};
|
940
1538
|
|
941
1539
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
942
|
-
import { EditorView as
|
1540
|
+
import { EditorView as EditorView5, keymap as keymap2 } from "@codemirror/view";
|
943
1541
|
import defaultsDeep from "lodash.defaultsdeep";
|
944
1542
|
import { invariant as invariant2 } from "@dxos/invariant";
|
945
1543
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
@@ -987,7 +1585,7 @@ var blast = (options = defaultOptions) => {
|
|
987
1585
|
};
|
988
1586
|
return [
|
989
1587
|
// Cursor moved.
|
990
|
-
|
1588
|
+
EditorView5.updateListener.of((update2) => {
|
991
1589
|
if (blaster?.node !== update2.view.scrollDOM) {
|
992
1590
|
if (blaster) {
|
993
1591
|
blaster.destroy();
|
@@ -1249,11 +1847,11 @@ var random = (min, max) => {
|
|
1249
1847
|
};
|
1250
1848
|
|
1251
1849
|
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
1252
|
-
import { EditorView as
|
1850
|
+
import { EditorView as EditorView7, keymap as keymap3 } from "@codemirror/view";
|
1253
1851
|
|
1254
1852
|
// packages/ui/react-ui-editor/src/extensions/command/hint.ts
|
1255
1853
|
import { RangeSetBuilder } from "@codemirror/state";
|
1256
|
-
import { Decoration as Decoration3, EditorView as
|
1854
|
+
import { Decoration as Decoration3, EditorView as EditorView6, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
|
1257
1855
|
|
1258
1856
|
// packages/ui/react-ui-editor/src/extensions/command/state.ts
|
1259
1857
|
import { StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
|
@@ -1419,7 +2017,7 @@ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
|
1419
2017
|
}
|
1420
2018
|
}, {
|
1421
2019
|
provide: (plugin) => [
|
1422
|
-
|
2020
|
+
EditorView6.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
|
1423
2021
|
]
|
1424
2022
|
});
|
1425
2023
|
|
@@ -1430,7 +2028,7 @@ var command = (options) => {
|
|
1430
2028
|
commandState,
|
1431
2029
|
keymap3.of(commandKeyBindings),
|
1432
2030
|
hintViewPlugin(options),
|
1433
|
-
|
2031
|
+
EditorView7.focusChangeEffect.of((_, focusing) => {
|
1434
2032
|
return focusing ? closeEffect.of(null) : null;
|
1435
2033
|
})
|
1436
2034
|
];
|
@@ -1439,16 +2037,16 @@ var command = (options) => {
|
|
1439
2037
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
1440
2038
|
import { invertedEffects } from "@codemirror/commands";
|
1441
2039
|
import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
|
1442
|
-
import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as
|
2040
|
+
import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView9, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
1443
2041
|
import sortBy from "lodash.sortby";
|
1444
|
-
import { useEffect, useMemo
|
2042
|
+
import { useEffect, useMemo as useMemo2 } from "react";
|
1445
2043
|
import { debounce as debounce2 } from "@dxos/async";
|
1446
2044
|
import { log as log4 } from "@dxos/log";
|
1447
2045
|
import { nonNullable } from "@dxos/util";
|
1448
2046
|
|
1449
2047
|
// packages/ui/react-ui-editor/src/extensions/selection.ts
|
1450
2048
|
import { Transaction } from "@codemirror/state";
|
1451
|
-
import { EditorView as
|
2049
|
+
import { EditorView as EditorView8, keymap as keymap4 } from "@codemirror/view";
|
1452
2050
|
import { debounce } from "@dxos/async";
|
1453
2051
|
import { invariant as invariant3 } from "@dxos/invariant";
|
1454
2052
|
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
@@ -1459,7 +2057,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1459
2057
|
return {
|
1460
2058
|
selection,
|
1461
2059
|
scrollIntoView: !scrollTo,
|
1462
|
-
effects: scrollTo ?
|
2060
|
+
effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
|
1463
2061
|
yMargin: 96
|
1464
2062
|
}) : void 0,
|
1465
2063
|
annotations: Transaction.userEvent.of(stateRestoreAnnotation)
|
@@ -1501,7 +2099,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
1501
2099
|
// setStateDebounced(id, {});
|
1502
2100
|
// },
|
1503
2101
|
// }),
|
1504
|
-
|
2102
|
+
EditorView8.updateListener.of(({ view, transactions }) => {
|
1505
2103
|
const id = view.state.facet(documentId);
|
1506
2104
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
1507
2105
|
return;
|
@@ -1582,7 +2180,7 @@ var commentsState = StateField4.define({
|
|
1582
2180
|
return value;
|
1583
2181
|
}
|
1584
2182
|
});
|
1585
|
-
var styles3 =
|
2183
|
+
var styles3 = EditorView9.theme({
|
1586
2184
|
".cm-comment, .cm-comment-current": {
|
1587
2185
|
margin: "0 -3px",
|
1588
2186
|
padding: "3px",
|
@@ -1602,7 +2200,7 @@ var createCommentMark = (id, isCurrent) => Decoration4.mark({
|
|
1602
2200
|
"data-comment-id": id
|
1603
2201
|
}
|
1604
2202
|
});
|
1605
|
-
var commentsDecorations =
|
2203
|
+
var commentsDecorations = EditorView9.decorations.compute([
|
1606
2204
|
commentsState
|
1607
2205
|
], (state) => {
|
1608
2206
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
@@ -1611,7 +2209,7 @@ var commentsDecorations = EditorView8.decorations.compute([
|
|
1611
2209
|
if (!range) {
|
1612
2210
|
log4.warn("Invalid range:", range, {
|
1613
2211
|
F: __dxlog_file7,
|
1614
|
-
L:
|
2212
|
+
L: 144,
|
1615
2213
|
S: void 0,
|
1616
2214
|
C: (f, a) => f(...a)
|
1617
2215
|
});
|
@@ -1625,7 +2223,7 @@ var commentsDecorations = EditorView8.decorations.compute([
|
|
1625
2223
|
return Decoration4.set(decorations);
|
1626
2224
|
});
|
1627
2225
|
var commentClickedEffect = StateEffect3.define();
|
1628
|
-
var handleCommentClick =
|
2226
|
+
var handleCommentClick = EditorView9.domEventHandlers({
|
1629
2227
|
click: (event, view) => {
|
1630
2228
|
let target = event.target;
|
1631
2229
|
const editorRoot = view.dom;
|
@@ -1664,7 +2262,7 @@ var trackPastedComments = (onUpdate) => {
|
|
1664
2262
|
}
|
1665
2263
|
};
|
1666
2264
|
return [
|
1667
|
-
|
2265
|
+
EditorView9.domEventHandlers({
|
1668
2266
|
cut: handleTrack,
|
1669
2267
|
copy: handleTrack
|
1670
2268
|
}),
|
@@ -1686,7 +2284,7 @@ var trackPastedComments = (onUpdate) => {
|
|
1686
2284
|
return effects;
|
1687
2285
|
}),
|
1688
2286
|
// Handle paste or the undo of comment deletion.
|
1689
|
-
|
2287
|
+
EditorView9.updateListener.of((update2) => {
|
1690
2288
|
const restore = [];
|
1691
2289
|
for (let i = 0; i < update2.transactions.length; i++) {
|
1692
2290
|
const tr = update2.transactions[i];
|
@@ -1745,7 +2343,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
1745
2343
|
var restoreCommentEffect = StateEffect3.define({
|
1746
2344
|
map: mapTrackedComment
|
1747
2345
|
});
|
1748
|
-
var
|
2346
|
+
var createComment2 = (view) => {
|
1749
2347
|
const options = view.state.facet(optionsFacet);
|
1750
2348
|
const { from, to } = view.state.selection.main;
|
1751
2349
|
if (from === to) {
|
@@ -1790,7 +2388,7 @@ var comments = (options = {}) => {
|
|
1790
2388
|
options.onCreate && keymap5.of([
|
1791
2389
|
{
|
1792
2390
|
key: shortcut,
|
1793
|
-
run: callbackWrapper(
|
2391
|
+
run: callbackWrapper(createComment2)
|
1794
2392
|
}
|
1795
2393
|
]),
|
1796
2394
|
//
|
@@ -1826,7 +2424,7 @@ var comments = (options = {}) => {
|
|
1826
2424
|
//
|
1827
2425
|
// Track deleted ranges and update ranges for decorations.
|
1828
2426
|
//
|
1829
|
-
|
2427
|
+
EditorView9.updateListener.of(({ view, state, changes }) => {
|
1830
2428
|
let mod = false;
|
1831
2429
|
const { comments: comments2, ...value } = state.field(commentsState);
|
1832
2430
|
changes.iterChanges((from, to, from2, to2) => {
|
@@ -1858,7 +2456,7 @@ var comments = (options = {}) => {
|
|
1858
2456
|
//
|
1859
2457
|
// Track selection/proximity.
|
1860
2458
|
//
|
1861
|
-
|
2459
|
+
EditorView9.updateListener.of(({ view, state }) => {
|
1862
2460
|
let min = Infinity;
|
1863
2461
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
1864
2462
|
const { head } = state.selection.main;
|
@@ -1912,7 +2510,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
|
|
1912
2510
|
anchor: range.from
|
1913
2511
|
} : void 0,
|
1914
2512
|
effects: [
|
1915
|
-
needsScroll ?
|
2513
|
+
needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
|
1916
2514
|
y: "center"
|
1917
2515
|
} : void 0) : [],
|
1918
2516
|
needsSelectionUpdate ? setSelection.of({
|
@@ -1923,415 +2521,179 @@ var scrollThreadIntoView = (view, id, center = true) => {
|
|
1923
2521
|
}
|
1924
2522
|
}
|
1925
2523
|
};
|
1926
|
-
var selectionOverlapsComment = (state) => {
|
1927
|
-
const commentState = state.field(commentsState, false);
|
1928
|
-
if (commentState === void 0) {
|
1929
|
-
return false;
|
1930
|
-
}
|
1931
|
-
const { selection } = state;
|
1932
|
-
for (const range of selection.ranges) {
|
1933
|
-
if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
|
1934
|
-
return true;
|
1935
|
-
}
|
1936
|
-
}
|
1937
|
-
return false;
|
1938
|
-
};
|
1939
|
-
var hasActiveSelection = (state) => {
|
1940
|
-
return state.selection.ranges.some((range) => !range.empty);
|
1941
|
-
};
|
1942
|
-
var ExternalCommentSync = class {
|
1943
|
-
constructor(view, id, subscribe, getComments) {
|
1944
|
-
this.destroy = () => {
|
1945
|
-
this.unsubscribe();
|
1946
|
-
};
|
1947
|
-
const updateComments = () => {
|
1948
|
-
const comments2 = getComments();
|
1949
|
-
if (id === view.state.facet(documentId)) {
|
1950
|
-
queueMicrotask(() => view.dispatch({
|
1951
|
-
effects: setComments.of({
|
1952
|
-
id,
|
1953
|
-
comments: comments2
|
1954
|
-
})
|
1955
|
-
}));
|
1956
|
-
}
|
1957
|
-
};
|
1958
|
-
this.unsubscribe = subscribe(updateComments);
|
1959
|
-
}
|
1960
|
-
};
|
1961
|
-
var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
|
1962
|
-
constructor(view) {
|
1963
|
-
return new ExternalCommentSync(view, id, subscribe, getComments);
|
1964
|
-
}
|
1965
|
-
});
|
1966
|
-
var useCommentState = () => {
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
if (id === view.state.facet(documentId)) {
|
1988
|
-
view.dispatch({
|
1989
|
-
effects: setComments.of({
|
1990
|
-
id,
|
1991
|
-
comments: comments2 ?? []
|
1992
|
-
})
|
1993
|
-
});
|
1994
|
-
}
|
1995
|
-
}
|
1996
|
-
});
|
1997
|
-
};
|
1998
|
-
var useCommentClickListener = (onCommentClick) => {
|
1999
|
-
return useMemo(() => EditorView8.updateListener.of((update2) => {
|
2000
|
-
update2.transactions.forEach((transaction) => {
|
2001
|
-
transaction.effects.forEach((effect) => {
|
2002
|
-
if (effect.is(commentClickedEffect)) {
|
2003
|
-
onCommentClick(effect.value);
|
2004
|
-
}
|
2005
|
-
});
|
2006
|
-
});
|
2007
|
-
}), [
|
2008
|
-
onCommentClick
|
2009
|
-
]);
|
2010
|
-
};
|
2011
|
-
|
2012
|
-
// packages/ui/react-ui-editor/src/extensions/debug.ts
|
2013
|
-
import { syntaxTree } from "@codemirror/language";
|
2014
|
-
import { StateField as StateField5 } from "@codemirror/state";
|
2015
|
-
var debugNodeLogger = (log8 = console.log) => {
|
2016
|
-
const logTokens = (state) => syntaxTree(state).iterate({
|
2017
|
-
enter: (node) => log8(node.type)
|
2018
|
-
});
|
2019
|
-
return StateField5.define({
|
2020
|
-
create: (state) => logTokens(state),
|
2021
|
-
update: (_, tr) => logTokens(tr.state)
|
2022
|
-
});
|
2023
|
-
};
|
2024
|
-
|
2025
|
-
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
2026
|
-
import { dropCursor, EditorView as EditorView9 } from "@codemirror/view";
|
2027
|
-
var styles4 = EditorView9.theme({
|
2028
|
-
".cm-dropCursor": {
|
2029
|
-
borderLeft: "2px solid var(--dx-accentText)",
|
2030
|
-
color: "var(--dx-accentText)",
|
2031
|
-
padding: "0 4px"
|
2032
|
-
},
|
2033
|
-
".cm-dropCursor:after": {
|
2034
|
-
content: '"\u2190"'
|
2035
|
-
}
|
2036
|
-
});
|
2037
|
-
var dropFile = (options = {}) => {
|
2038
|
-
return [
|
2039
|
-
styles4,
|
2040
|
-
dropCursor(),
|
2041
|
-
EditorView9.domEventHandlers({
|
2042
|
-
drop: (event, view) => {
|
2043
|
-
event.preventDefault();
|
2044
|
-
const files = event.dataTransfer?.files;
|
2045
|
-
const pos = view.posAtCoords(event);
|
2046
|
-
if (files?.length && pos !== null) {
|
2047
|
-
view.dispatch({
|
2048
|
-
selection: {
|
2049
|
-
anchor: pos
|
2050
|
-
}
|
2051
|
-
});
|
2052
|
-
options.onDrop?.(view, {
|
2053
|
-
files
|
2054
|
-
});
|
2055
|
-
}
|
2056
|
-
}
|
2057
|
-
})
|
2058
|
-
];
|
2059
|
-
};
|
2060
|
-
|
2061
|
-
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
2062
|
-
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
2063
|
-
import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
2064
|
-
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
2065
|
-
import { searchKeymap } from "@codemirror/search";
|
2066
|
-
import { EditorState } from "@codemirror/state";
|
2067
|
-
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
2068
|
-
import { EditorView as EditorView11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
2069
|
-
import defaultsDeep2 from "lodash.defaultsdeep";
|
2070
|
-
import merge from "lodash.merge";
|
2071
|
-
import { generateName } from "@dxos/display-name";
|
2072
|
-
import { log as log5 } from "@dxos/log";
|
2073
|
-
import { hueTokens } from "@dxos/react-ui-theme";
|
2074
|
-
import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
2075
|
-
|
2076
|
-
// packages/ui/react-ui-editor/src/extensions/focus.ts
|
2077
|
-
import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
|
2078
|
-
import { EditorView as EditorView10 } from "@codemirror/view";
|
2079
|
-
var focusEffect = StateEffect4.define();
|
2080
|
-
var focusField = StateField6.define({
|
2081
|
-
create: () => false,
|
2082
|
-
update: (value, tr) => {
|
2083
|
-
for (const effect of tr.effects) {
|
2084
|
-
if (effect.is(focusEffect)) {
|
2085
|
-
return effect.value;
|
2086
|
-
}
|
2087
|
-
}
|
2088
|
-
return value;
|
2089
|
-
}
|
2090
|
-
});
|
2091
|
-
var focus = [
|
2092
|
-
focusField,
|
2093
|
-
EditorView10.domEventHandlers({
|
2094
|
-
focus: (event, view) => {
|
2095
|
-
setTimeout(() => view.dispatch({
|
2096
|
-
effects: focusEffect.of(true)
|
2097
|
-
}));
|
2098
|
-
},
|
2099
|
-
blur: (event, view) => {
|
2100
|
-
setTimeout(() => view.dispatch({
|
2101
|
-
effects: focusEffect.of(false)
|
2102
|
-
}));
|
2103
|
-
}
|
2104
|
-
})
|
2105
|
-
];
|
2106
|
-
|
2107
|
-
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
2108
|
-
import { mx } from "@dxos/react-ui-theme";
|
2109
|
-
var headings = {
|
2110
|
-
1: "text-4xl",
|
2111
|
-
2: "text-3xl",
|
2112
|
-
3: "text-2xl",
|
2113
|
-
4: "text-xl",
|
2114
|
-
5: "text-lg",
|
2115
|
-
6: "text-md"
|
2116
|
-
};
|
2117
|
-
var theme = {
|
2118
|
-
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
2119
|
-
codeMark: "font-mono text-primary-500",
|
2120
|
-
mark: "opacity-50",
|
2121
|
-
heading: (level) => {
|
2122
|
-
return mx(headings[level], "dark:text-primary-400");
|
2123
|
-
}
|
2124
|
-
};
|
2125
|
-
|
2126
|
-
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
2127
|
-
import get from "lodash.get";
|
2128
|
-
import { tokens } from "@dxos/react-ui-theme";
|
2129
|
-
var getToken = (path, defaultValue) => {
|
2130
|
-
const value = get(tokens, path, defaultValue);
|
2131
|
-
return value?.toString() ?? "";
|
2132
|
-
};
|
2133
|
-
var fontBody = getToken("fontFamily.body");
|
2134
|
-
var fontMono = getToken("fontFamily.mono");
|
2135
|
-
|
2136
|
-
// packages/ui/react-ui-editor/src/styles/theme.ts
|
2137
|
-
var defaultTheme = {
|
2138
|
-
"&": {},
|
2139
|
-
"&.cm-focused": {
|
2140
|
-
outline: "none"
|
2141
|
-
},
|
2142
|
-
/**
|
2143
|
-
* Scroller
|
2144
|
-
*/
|
2145
|
-
".cm-scroller": {
|
2146
|
-
overflowY: "auto"
|
2147
|
-
},
|
2148
|
-
/**
|
2149
|
-
* Content
|
2150
|
-
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
2151
|
-
*/
|
2152
|
-
".cm-content": {
|
2153
|
-
padding: "unset",
|
2154
|
-
fontFamily: fontBody,
|
2155
|
-
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
2156
|
-
fontSize: "16px",
|
2157
|
-
lineHeight: 1.5,
|
2158
|
-
color: "unset"
|
2159
|
-
},
|
2160
|
-
/**
|
2161
|
-
* Gutters
|
2162
|
-
* NOTE: Gutters should have the same top margin as the content.
|
2163
|
-
* NOTE: They can't be transparent since the content needs to scroll below.
|
2164
|
-
*/
|
2165
|
-
".cm-gutters": {
|
2166
|
-
background: "var(--surface-bg)",
|
2167
|
-
borderRight: "none"
|
2168
|
-
},
|
2169
|
-
".cm-gutter": {},
|
2170
|
-
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
2171
|
-
minWidth: "40px",
|
2172
|
-
alignContent: "center"
|
2173
|
-
},
|
2174
|
-
/**
|
2175
|
-
* Height is set to match the corresponding line.
|
2176
|
-
*/
|
2177
|
-
".cm-gutterElement": {
|
2178
|
-
alignItems: "center",
|
2179
|
-
fontSize: "16px"
|
2180
|
-
},
|
2181
|
-
/**
|
2182
|
-
* Line.
|
2183
|
-
*/
|
2184
|
-
".cm-line": {
|
2185
|
-
paddingInline: 0
|
2186
|
-
},
|
2187
|
-
".cm-activeLine": {
|
2188
|
-
background: "var(--dx-cmActiveLine)"
|
2189
|
-
},
|
2190
|
-
/**
|
2191
|
-
* Cursor (layer).
|
2192
|
-
*/
|
2193
|
-
".cm-cursor, .cm-dropCursor": {
|
2194
|
-
borderLeft: "2px solid var(--dx-cmCursor)"
|
2195
|
-
},
|
2196
|
-
".cm-placeholder": {
|
2197
|
-
color: "var(--dx-subdued)"
|
2198
|
-
},
|
2199
|
-
/**
|
2200
|
-
* Selection (layer).
|
2201
|
-
*/
|
2202
|
-
".cm-selectionBackground": {
|
2203
|
-
background: "var(--dx-cmSelection)"
|
2204
|
-
},
|
2205
|
-
/**
|
2206
|
-
* Search.
|
2207
|
-
* NOTE: Matches comment.
|
2208
|
-
*/
|
2209
|
-
".cm-searchMatch": {
|
2210
|
-
margin: "0 -3px",
|
2211
|
-
padding: "3px",
|
2212
|
-
borderRadius: "3px",
|
2213
|
-
background: "var(--dx-cmHighlightSurface)",
|
2214
|
-
color: "var(--dx-cmHighlight)"
|
2215
|
-
},
|
2216
|
-
".cm-searchMatch-selected": {
|
2217
|
-
textDecoration: "underline"
|
2218
|
-
},
|
2219
|
-
/**
|
2220
|
-
* Link.
|
2221
|
-
*/
|
2222
|
-
".cm-link": {
|
2223
|
-
textDecorationLine: "underline",
|
2224
|
-
textDecorationThickness: "1px",
|
2225
|
-
textUnderlineOffset: "2px",
|
2226
|
-
borderRadius: ".125rem"
|
2227
|
-
},
|
2228
|
-
".cm-link > span": {
|
2229
|
-
color: "var(--dx-accentText)"
|
2230
|
-
},
|
2231
|
-
/**
|
2232
|
-
* Tooltip.
|
2233
|
-
*/
|
2234
|
-
".cm-tooltip": {
|
2235
|
-
background: "var(--dx-base)"
|
2236
|
-
},
|
2237
|
-
".cm-tooltip-below": {},
|
2238
|
-
/**
|
2239
|
-
* Autocomplete.
|
2240
|
-
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
2241
|
-
*/
|
2242
|
-
".cm-tooltip.cm-tooltip-autocomplete": {
|
2243
|
-
marginTop: "4px",
|
2244
|
-
marginLeft: "-3px"
|
2245
|
-
},
|
2246
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
2247
|
-
maxHeight: "20em"
|
2248
|
-
},
|
2249
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
2250
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
2251
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
2252
|
-
paddingLeft: "4px !important",
|
2253
|
-
borderBottom: "none !important",
|
2254
|
-
color: "var(--dx-accentText)"
|
2255
|
-
},
|
2256
|
-
".cm-tooltip.cm-completionInfo": {
|
2257
|
-
width: "360px !important",
|
2258
|
-
margin: "-10px 1px 0 1px",
|
2259
|
-
padding: "8px !important",
|
2260
|
-
borderColor: "var(--dx-separator)"
|
2261
|
-
},
|
2262
|
-
".cm-completionIcon": {
|
2263
|
-
display: "none"
|
2264
|
-
},
|
2265
|
-
".cm-completionLabel": {
|
2266
|
-
fontFamily: fontBody
|
2267
|
-
},
|
2268
|
-
".cm-completionMatchedText": {
|
2269
|
-
textDecoration: "none !important",
|
2270
|
-
opacity: 0.5
|
2271
|
-
},
|
2272
|
-
/**
|
2273
|
-
* Panels
|
2274
|
-
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
2275
|
-
*
|
2276
|
-
* Find/replace panel.
|
2277
|
-
* <div class="cm-announced">...</div>
|
2278
|
-
* <div class="cm-scroller">...</div>
|
2279
|
-
* <div class="cm-panels cm-panels-bottom">
|
2280
|
-
* <div class="cm-search cm-panel">
|
2281
|
-
* <input class="cm-textfield" />
|
2282
|
-
* <button class="cm-button">...</button>
|
2283
|
-
* <label><input type="checkbox" />...</label>
|
2284
|
-
* </div>
|
2285
|
-
* </div
|
2286
|
-
*/
|
2287
|
-
// TODO(burdon): Implement custom panel (with icon buttons).
|
2288
|
-
".cm-panels": {},
|
2289
|
-
".cm-panel": {
|
2290
|
-
fontFamily: fontBody,
|
2291
|
-
backgroundColor: "var(--surface-bg)"
|
2292
|
-
},
|
2293
|
-
".cm-panel input, .cm-panel button, .cm-panel label": {
|
2294
|
-
color: "var(--dx-subdued)",
|
2295
|
-
fontFamily: fontBody,
|
2296
|
-
fontSize: "14px",
|
2297
|
-
all: "unset",
|
2298
|
-
margin: "3px !important",
|
2299
|
-
padding: "2px 6px !important",
|
2300
|
-
outline: "1px solid transparent"
|
2301
|
-
},
|
2302
|
-
".cm-panel input, .cm-panel button": {
|
2303
|
-
backgroundColor: "var(--dx-input)"
|
2304
|
-
},
|
2305
|
-
".cm-panel input:focus, .cm-panel button:focus": {
|
2306
|
-
outline: "1px solid var(--dx-accentFocusIndicator)"
|
2307
|
-
},
|
2308
|
-
".cm-panel label": {
|
2309
|
-
display: "inline-flex",
|
2310
|
-
alignItems: "center",
|
2311
|
-
cursor: "pointer"
|
2312
|
-
},
|
2313
|
-
".cm-panel input.cm-textfield": {},
|
2314
|
-
".cm-panel input[type=checkbox]": {
|
2315
|
-
width: "8px",
|
2316
|
-
height: "8px",
|
2317
|
-
marginRight: "6px !important",
|
2318
|
-
padding: "2px !important",
|
2319
|
-
color: "var(--dx-accentFocusIndicator)"
|
2320
|
-
},
|
2321
|
-
".cm-panel button": {
|
2322
|
-
"&:hover": {
|
2323
|
-
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
2324
|
-
},
|
2325
|
-
"&:active": {
|
2326
|
-
backgroundColor: "var(--dx-accentSurfaceHover)"
|
2524
|
+
var selectionOverlapsComment = (state) => {
|
2525
|
+
const commentState = state.field(commentsState, false);
|
2526
|
+
if (commentState === void 0) {
|
2527
|
+
return false;
|
2528
|
+
}
|
2529
|
+
const { selection } = state;
|
2530
|
+
for (const range of selection.ranges) {
|
2531
|
+
if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
|
2532
|
+
return true;
|
2533
|
+
}
|
2534
|
+
}
|
2535
|
+
return false;
|
2536
|
+
};
|
2537
|
+
var hasActiveSelection = (state) => {
|
2538
|
+
return state.selection.ranges.some((range) => !range.empty);
|
2539
|
+
};
|
2540
|
+
var ExternalCommentSync = class {
|
2541
|
+
constructor(view, id, subscribe, getComments) {
|
2542
|
+
this.destroy = () => {
|
2543
|
+
this.unsubscribe();
|
2544
|
+
};
|
2545
|
+
const updateComments = () => {
|
2546
|
+
const comments2 = getComments();
|
2547
|
+
if (id === view.state.facet(documentId)) {
|
2548
|
+
queueMicrotask(() => view.dispatch({
|
2549
|
+
effects: setComments.of({
|
2550
|
+
id,
|
2551
|
+
comments: comments2
|
2552
|
+
})
|
2553
|
+
}));
|
2554
|
+
}
|
2555
|
+
};
|
2556
|
+
this.unsubscribe = subscribe(updateComments);
|
2557
|
+
}
|
2558
|
+
};
|
2559
|
+
var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
|
2560
|
+
constructor(view) {
|
2561
|
+
return new ExternalCommentSync(view, id, subscribe, getComments);
|
2562
|
+
}
|
2563
|
+
});
|
2564
|
+
var useCommentState = (state) => {
|
2565
|
+
return useMemo2(() => EditorView9.updateListener.of((update2) => {
|
2566
|
+
if (update2.docChanged || update2.selectionSet) {
|
2567
|
+
state.comment = selectionOverlapsComment(update2.state);
|
2568
|
+
state.selection = hasActiveSelection(update2.state);
|
2569
|
+
}
|
2570
|
+
}), [
|
2571
|
+
state
|
2572
|
+
]);
|
2573
|
+
};
|
2574
|
+
var useComments = (view, id, comments2) => {
|
2575
|
+
useEffect(() => {
|
2576
|
+
if (view) {
|
2577
|
+
if (id === view.state.facet(documentId)) {
|
2578
|
+
view.dispatch({
|
2579
|
+
effects: setComments.of({
|
2580
|
+
id,
|
2581
|
+
comments: comments2 ?? []
|
2582
|
+
})
|
2583
|
+
});
|
2584
|
+
}
|
2327
2585
|
}
|
2586
|
+
});
|
2587
|
+
};
|
2588
|
+
var useCommentClickListener = (onCommentClick) => {
|
2589
|
+
return useMemo2(() => EditorView9.updateListener.of((update2) => {
|
2590
|
+
update2.transactions.forEach((transaction) => {
|
2591
|
+
transaction.effects.forEach((effect) => {
|
2592
|
+
if (effect.is(commentClickedEffect)) {
|
2593
|
+
onCommentClick(effect.value);
|
2594
|
+
}
|
2595
|
+
});
|
2596
|
+
});
|
2597
|
+
}), [
|
2598
|
+
onCommentClick
|
2599
|
+
]);
|
2600
|
+
};
|
2601
|
+
|
2602
|
+
// packages/ui/react-ui-editor/src/extensions/debug.ts
|
2603
|
+
import { syntaxTree } from "@codemirror/language";
|
2604
|
+
import { StateField as StateField5 } from "@codemirror/state";
|
2605
|
+
var debugNodeLogger = (log8 = console.log) => {
|
2606
|
+
const logTokens = (state) => syntaxTree(state).iterate({
|
2607
|
+
enter: (node) => log8(node.type)
|
2608
|
+
});
|
2609
|
+
return StateField5.define({
|
2610
|
+
create: (state) => logTokens(state),
|
2611
|
+
update: (_, tr) => logTokens(tr.state)
|
2612
|
+
});
|
2613
|
+
};
|
2614
|
+
|
2615
|
+
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
2616
|
+
import { dropCursor, EditorView as EditorView10 } from "@codemirror/view";
|
2617
|
+
var styles4 = EditorView10.theme({
|
2618
|
+
".cm-dropCursor": {
|
2619
|
+
borderLeft: "2px solid var(--dx-accentText)",
|
2620
|
+
color: "var(--dx-accentText)",
|
2621
|
+
padding: "0 4px"
|
2328
2622
|
},
|
2329
|
-
".cm-
|
2330
|
-
|
2331
|
-
borderTop: "1px solid var(--dx-separator)"
|
2623
|
+
".cm-dropCursor:after": {
|
2624
|
+
content: '"\u2190"'
|
2332
2625
|
}
|
2626
|
+
});
|
2627
|
+
var dropFile = (options = {}) => {
|
2628
|
+
return [
|
2629
|
+
styles4,
|
2630
|
+
dropCursor(),
|
2631
|
+
EditorView10.domEventHandlers({
|
2632
|
+
drop: (event, view) => {
|
2633
|
+
event.preventDefault();
|
2634
|
+
const files = event.dataTransfer?.files;
|
2635
|
+
const pos = view.posAtCoords(event);
|
2636
|
+
if (files?.length && pos !== null) {
|
2637
|
+
view.dispatch({
|
2638
|
+
selection: {
|
2639
|
+
anchor: pos
|
2640
|
+
}
|
2641
|
+
});
|
2642
|
+
options.onDrop?.(view, {
|
2643
|
+
files
|
2644
|
+
});
|
2645
|
+
}
|
2646
|
+
}
|
2647
|
+
})
|
2648
|
+
];
|
2333
2649
|
};
|
2334
2650
|
|
2651
|
+
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
2652
|
+
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
2653
|
+
import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
2654
|
+
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
2655
|
+
import { searchKeymap } from "@codemirror/search";
|
2656
|
+
import { EditorState } from "@codemirror/state";
|
2657
|
+
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
2658
|
+
import { EditorView as EditorView12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
2659
|
+
import defaultsDeep2 from "lodash.defaultsdeep";
|
2660
|
+
import merge from "lodash.merge";
|
2661
|
+
import { generateName } from "@dxos/display-name";
|
2662
|
+
import { log as log5 } from "@dxos/log";
|
2663
|
+
import { hueTokens } from "@dxos/react-ui-theme";
|
2664
|
+
import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
2665
|
+
|
2666
|
+
// packages/ui/react-ui-editor/src/extensions/focus.ts
|
2667
|
+
import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
|
2668
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
2669
|
+
var focusEffect = StateEffect4.define();
|
2670
|
+
var focusField = StateField6.define({
|
2671
|
+
create: () => false,
|
2672
|
+
update: (value, tr) => {
|
2673
|
+
for (const effect of tr.effects) {
|
2674
|
+
if (effect.is(focusEffect)) {
|
2675
|
+
return effect.value;
|
2676
|
+
}
|
2677
|
+
}
|
2678
|
+
return value;
|
2679
|
+
}
|
2680
|
+
});
|
2681
|
+
var focus = [
|
2682
|
+
focusField,
|
2683
|
+
EditorView11.domEventHandlers({
|
2684
|
+
focus: (event, view) => {
|
2685
|
+
setTimeout(() => view.dispatch({
|
2686
|
+
effects: focusEffect.of(true)
|
2687
|
+
}));
|
2688
|
+
},
|
2689
|
+
blur: (event, view) => {
|
2690
|
+
setTimeout(() => view.dispatch({
|
2691
|
+
effects: focusEffect.of(false)
|
2692
|
+
}));
|
2693
|
+
}
|
2694
|
+
})
|
2695
|
+
];
|
2696
|
+
|
2335
2697
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
2336
2698
|
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
|
2337
2699
|
var preventNewline = EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
|
@@ -2357,7 +2719,7 @@ var createBasicExtensions = (_props) => {
|
|
2357
2719
|
const props = defaultsDeep2({}, _props, defaultBasicOptions);
|
2358
2720
|
return [
|
2359
2721
|
// NOTE: Doesn't catch errors in keymap functions.
|
2360
|
-
|
2722
|
+
EditorView12.exceptionSink.of((err) => {
|
2361
2723
|
log5.catch(err, void 0, {
|
2362
2724
|
F: __dxlog_file8,
|
2363
2725
|
L: 96,
|
@@ -2376,11 +2738,11 @@ var createBasicExtensions = (_props) => {
|
|
2376
2738
|
props.highlightActiveLine && highlightActiveLine(),
|
2377
2739
|
props.history && history(),
|
2378
2740
|
props.lineNumbers && lineNumbers(),
|
2379
|
-
props.lineWrapping &&
|
2741
|
+
props.lineWrapping && EditorView12.lineWrapping,
|
2380
2742
|
props.placeholder && placeholder(props.placeholder),
|
2381
2743
|
props.readonly && [
|
2382
2744
|
EditorState.readOnly.of(true),
|
2383
|
-
|
2745
|
+
EditorView12.editable.of(false)
|
2384
2746
|
],
|
2385
2747
|
props.scrollPastEnd && scrollPastEnd(),
|
2386
2748
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
@@ -2409,14 +2771,14 @@ var defaultThemeSlots = {
|
|
2409
2771
|
var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
|
2410
2772
|
const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
|
2411
2773
|
return [
|
2412
|
-
|
2413
|
-
|
2774
|
+
EditorView12.darkTheme.of(themeMode === "dark"),
|
2775
|
+
EditorView12.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
|
2414
2776
|
// https://github.com/codemirror/theme-one-dark
|
2415
2777
|
_syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
|
2416
|
-
slots.editor?.className &&
|
2778
|
+
slots.editor?.className && EditorView12.editorAttributes.of({
|
2417
2779
|
class: slots.editor.className
|
2418
2780
|
}),
|
2419
|
-
slots.content?.className &&
|
2781
|
+
slots.content?.className && EditorView12.contentAttributes.of({
|
2420
2782
|
class: slots.content.className
|
2421
2783
|
})
|
2422
2784
|
].filter(isNotFalsy3);
|
@@ -2445,8 +2807,8 @@ var createDataExtensions = ({ id, text, space, identity }) => {
|
|
2445
2807
|
|
2446
2808
|
// packages/ui/react-ui-editor/src/extensions/folding.tsx
|
2447
2809
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
2448
|
-
import { EditorView as
|
2449
|
-
import
|
2810
|
+
import { EditorView as EditorView13 } from "@codemirror/view";
|
2811
|
+
import React3 from "react";
|
2450
2812
|
import { Icon } from "@dxos/react-ui";
|
2451
2813
|
var folding = (_props = {}) => [
|
2452
2814
|
codeFolding({
|
@@ -2459,7 +2821,7 @@ var folding = (_props = {}) => [
|
|
2459
2821
|
const el = createElement("div", {
|
2460
2822
|
className: "flex h-full items-center"
|
2461
2823
|
});
|
2462
|
-
return renderRoot(el, /* @__PURE__ */
|
2824
|
+
return renderRoot(el, /* @__PURE__ */ React3.createElement(Icon, {
|
2463
2825
|
icon: "ph--caret-right--regular",
|
2464
2826
|
size: 3,
|
2465
2827
|
classNames: [
|
@@ -2469,7 +2831,7 @@ var folding = (_props = {}) => [
|
|
2469
2831
|
}));
|
2470
2832
|
}
|
2471
2833
|
}),
|
2472
|
-
|
2834
|
+
EditorView13.theme({
|
2473
2835
|
".cm-foldGutter": {
|
2474
2836
|
opacity: 0.3,
|
2475
2837
|
transition: "opacity 0.3s",
|
@@ -2482,14 +2844,14 @@ var folding = (_props = {}) => [
|
|
2482
2844
|
];
|
2483
2845
|
|
2484
2846
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
2485
|
-
import { EditorView as
|
2847
|
+
import { EditorView as EditorView14 } from "@codemirror/view";
|
2486
2848
|
var listener = ({ onFocus, onChange }) => {
|
2487
2849
|
const extensions = [];
|
2488
|
-
onFocus && extensions.push(
|
2850
|
+
onFocus && extensions.push(EditorView14.focusChangeEffect.of((_, focusing) => {
|
2489
2851
|
onFocus(focusing);
|
2490
2852
|
return null;
|
2491
2853
|
}));
|
2492
|
-
onChange && extensions.push(
|
2854
|
+
onChange && extensions.push(EditorView14.updateListener.of((update2) => {
|
2493
2855
|
onChange(update2.state.doc.toString(), update2.state.facet(documentId));
|
2494
2856
|
}));
|
2495
2857
|
return extensions;
|
@@ -2499,8 +2861,8 @@ var listener = ({ onFocus, onChange }) => {
|
|
2499
2861
|
import { snippet } from "@codemirror/autocomplete";
|
2500
2862
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
2501
2863
|
import { EditorSelection } from "@codemirror/state";
|
2502
|
-
import { EditorView as
|
2503
|
-
import { useMemo as
|
2864
|
+
import { EditorView as EditorView15, keymap as keymap7 } from "@codemirror/view";
|
2865
|
+
import { useMemo as useMemo3 } from "react";
|
2504
2866
|
var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
2505
2867
|
var Inline;
|
2506
2868
|
(function(Inline2) {
|
@@ -3587,65 +3949,56 @@ var getFormatting = (state) => {
|
|
3587
3949
|
listStyle: listStyle || null
|
3588
3950
|
};
|
3589
3951
|
};
|
3590
|
-
var useFormattingState = () => {
|
3591
|
-
|
3592
|
-
const observer = useMemo2(() => EditorView14.updateListener.of((update2) => {
|
3952
|
+
var useFormattingState = (state) => {
|
3953
|
+
return useMemo3(() => EditorView15.updateListener.of((update2) => {
|
3593
3954
|
if (update2.docChanged || update2.selectionSet) {
|
3594
|
-
|
3595
|
-
|
3596
|
-
if (!prevState || !formattingEquals(prevState, newState)) {
|
3597
|
-
return newState;
|
3598
|
-
}
|
3599
|
-
return prevState;
|
3955
|
+
Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
|
3956
|
+
state[key] = active;
|
3600
3957
|
});
|
3601
3958
|
}
|
3602
3959
|
}), []);
|
3603
|
-
return [
|
3604
|
-
state,
|
3605
|
-
observer
|
3606
|
-
];
|
3607
3960
|
};
|
3608
3961
|
|
3609
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
3610
|
-
var
|
3962
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/editorAction.ts
|
3963
|
+
var processEditorPayload = (view, { type, data }) => {
|
3611
3964
|
let inlineType, listType;
|
3612
|
-
switch (
|
3965
|
+
switch (type) {
|
3613
3966
|
case "heading":
|
3614
|
-
setHeading(parseInt(
|
3967
|
+
setHeading(parseInt(data))(view);
|
3615
3968
|
break;
|
3616
3969
|
case "strong":
|
3617
3970
|
case "emphasis":
|
3618
3971
|
case "strikethrough":
|
3619
3972
|
case "code":
|
3620
|
-
inlineType =
|
3621
|
-
(typeof
|
3973
|
+
inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
3974
|
+
(typeof data === "boolean" ? setStyle(inlineType, data) : toggleStyle(inlineType))(view);
|
3622
3975
|
break;
|
3623
3976
|
case "list-ordered":
|
3624
3977
|
case "list-bullet":
|
3625
3978
|
case "list-task":
|
3626
|
-
listType =
|
3627
|
-
(
|
3979
|
+
listType = type === "list-ordered" ? List.Ordered : type === "list-bullet" ? List.Bullet : List.Task;
|
3980
|
+
(data === false ? removeList(listType) : data === true ? addList(listType) : toggleList(listType))(view);
|
3628
3981
|
break;
|
3629
3982
|
case "blockquote":
|
3630
|
-
(
|
3983
|
+
(data === false ? removeBlockquote : data === true ? addBlockquote : toggleBlockquote)(view);
|
3631
3984
|
break;
|
3632
3985
|
case "codeblock":
|
3633
|
-
(
|
3986
|
+
(data === false ? removeCodeblock : addCodeblock)(view);
|
3634
3987
|
break;
|
3635
3988
|
case "table":
|
3636
3989
|
insertTable(view);
|
3637
3990
|
break;
|
3638
3991
|
case "link":
|
3639
|
-
(
|
3992
|
+
(data === false ? removeLink : addLink())(view);
|
3640
3993
|
break;
|
3641
3994
|
case "image":
|
3642
3995
|
addLink({
|
3643
|
-
url:
|
3996
|
+
url: data,
|
3644
3997
|
image: true
|
3645
3998
|
})(view);
|
3646
3999
|
break;
|
3647
4000
|
case "comment":
|
3648
|
-
|
4001
|
+
createComment2(view);
|
3649
4002
|
break;
|
3650
4003
|
}
|
3651
4004
|
requestAnimationFrame(() => {
|
@@ -3909,9 +4262,9 @@ var convertTreeToJson = (state) => {
|
|
3909
4262
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
3910
4263
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
3911
4264
|
import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
|
3912
|
-
import { EditorView as
|
4265
|
+
import { EditorView as EditorView19, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
3913
4266
|
import { invariant as invariant4 } from "@dxos/invariant";
|
3914
|
-
import { mx as
|
4267
|
+
import { mx as mx4 } from "@dxos/react-ui-theme";
|
3915
4268
|
|
3916
4269
|
// packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
|
3917
4270
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
@@ -4060,7 +4413,7 @@ var getValidUrl = (str) => {
|
|
4060
4413
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
4061
4414
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
4062
4415
|
import { StateField as StateField8 } from "@codemirror/state";
|
4063
|
-
import { Decoration as Decoration5, EditorView as
|
4416
|
+
import { Decoration as Decoration5, EditorView as EditorView16, WidgetType as WidgetType3 } from "@codemirror/view";
|
4064
4417
|
var image = (_options = {}) => {
|
4065
4418
|
return [
|
4066
4419
|
StateField8.define({
|
@@ -4088,7 +4441,7 @@ var image = (_options = {}) => {
|
|
4088
4441
|
add: buildDecorations(from, to, tr.state)
|
4089
4442
|
});
|
4090
4443
|
},
|
4091
|
-
provide: (field) =>
|
4444
|
+
provide: (field) => EditorView16.decorations.from(field)
|
4092
4445
|
})
|
4093
4446
|
];
|
4094
4447
|
};
|
@@ -4148,10 +4501,10 @@ var ImageWidget = class extends WidgetType3 {
|
|
4148
4501
|
};
|
4149
4502
|
|
4150
4503
|
// packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
|
4151
|
-
import { EditorView as
|
4504
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
4152
4505
|
var bulletListIndentationWidth = 24;
|
4153
4506
|
var orderedListIndentationWidth = 36;
|
4154
|
-
var formattingStyles =
|
4507
|
+
var formattingStyles = EditorView17.theme({
|
4155
4508
|
/**
|
4156
4509
|
* Horizontal rule.
|
4157
4510
|
*/
|
@@ -4245,18 +4598,39 @@ var formattingStyles = EditorView16.theme({
|
|
4245
4598
|
height: "auto",
|
4246
4599
|
borderTop: "0.5rem solid transparent",
|
4247
4600
|
borderBottom: "0.5rem solid transparent"
|
4601
|
+
},
|
4602
|
+
".cm-image-with-loader": {
|
4603
|
+
display: "block",
|
4604
|
+
opacity: "0",
|
4605
|
+
transitionDuration: "350ms",
|
4606
|
+
transitionProperty: "opacity"
|
4607
|
+
},
|
4608
|
+
".cm-image-with-loader.cm-loaded-image": {
|
4609
|
+
opacity: "1"
|
4610
|
+
},
|
4611
|
+
".cm-image-wrapper": {
|
4612
|
+
"grid-template-columns": "1fr",
|
4613
|
+
display: "grid",
|
4614
|
+
margin: "0.5rem 0",
|
4615
|
+
overflow: "hidden",
|
4616
|
+
transitionDuration: "350ms",
|
4617
|
+
transitionProperty: "height",
|
4618
|
+
"& > *": {
|
4619
|
+
"grid-row-start": 1,
|
4620
|
+
"grid-column-start": 1
|
4621
|
+
}
|
4248
4622
|
}
|
4249
4623
|
});
|
4250
4624
|
|
4251
4625
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
4252
4626
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
4253
4627
|
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
|
4254
|
-
import { Decoration as Decoration6, EditorView as
|
4628
|
+
import { Decoration as Decoration6, EditorView as EditorView18, WidgetType as WidgetType4 } from "@codemirror/view";
|
4255
4629
|
var table = (options = {}) => {
|
4256
4630
|
return StateField9.define({
|
4257
4631
|
create: (state) => update(state, options),
|
4258
4632
|
update: (_, tr) => update(tr.state, options),
|
4259
|
-
provide: (field) =>
|
4633
|
+
provide: (field) => EditorView18.decorations.from(field)
|
4260
4634
|
});
|
4261
4635
|
};
|
4262
4636
|
var update = (state, _options) => {
|
@@ -4440,16 +4814,16 @@ var TextWidget = class extends WidgetType5 {
|
|
4440
4814
|
};
|
4441
4815
|
var hide = Decoration7.replace({});
|
4442
4816
|
var blockQuote = Decoration7.line({
|
4443
|
-
class:
|
4817
|
+
class: mx4("cm-blockquote")
|
4444
4818
|
});
|
4445
4819
|
var fencedCodeLine = Decoration7.line({
|
4446
|
-
class:
|
4820
|
+
class: mx4("cm-code cm-codeblock-line")
|
4447
4821
|
});
|
4448
4822
|
var fencedCodeLineFirst = Decoration7.line({
|
4449
|
-
class:
|
4823
|
+
class: mx4("cm-code cm-codeblock-line", "cm-codeblock-first")
|
4450
4824
|
});
|
4451
4825
|
var fencedCodeLineLast = Decoration7.line({
|
4452
|
-
class:
|
4826
|
+
class: mx4("cm-code cm-codeblock-line", "cm-codeblock-last")
|
4453
4827
|
});
|
4454
4828
|
var commentBlockLine = fencedCodeLine;
|
4455
4829
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
@@ -4790,9 +5164,9 @@ var decorateMarkdown = (options = {}) => {
|
|
4790
5164
|
}
|
4791
5165
|
}, {
|
4792
5166
|
provide: (plugin) => [
|
4793
|
-
|
4794
|
-
|
4795
|
-
|
5167
|
+
EditorView19.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
5168
|
+
EditorView19.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
5169
|
+
EditorView19.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
|
4796
5170
|
]
|
4797
5171
|
}),
|
4798
5172
|
image(),
|
@@ -4880,16 +5254,19 @@ var mention = ({ debug, onSearch }) => {
|
|
4880
5254
|
import { keymap as keymap9 } from "@codemirror/view";
|
4881
5255
|
import { vim } from "@replit/codemirror-vim";
|
4882
5256
|
import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
|
5257
|
+
import { S } from "@dxos/echo-schema";
|
4883
5258
|
var EditorViewModes = [
|
4884
5259
|
"preview",
|
4885
5260
|
"readonly",
|
4886
5261
|
"source"
|
4887
5262
|
];
|
5263
|
+
var EditorViewMode = S.Union(...EditorViewModes.map((mode) => S.Literal(mode)));
|
4888
5264
|
var EditorInputModes = [
|
4889
5265
|
"default",
|
4890
5266
|
"vim",
|
4891
5267
|
"vscode"
|
4892
5268
|
];
|
5269
|
+
var EditorInputMode = S.Union(...EditorInputModes.map((mode) => S.Literal(mode)));
|
4893
5270
|
var editorInputMode = singleValueFacet({});
|
4894
5271
|
var InputModeExtensions = {
|
4895
5272
|
default: [],
|
@@ -4976,428 +5353,29 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
4976
5353
|
];
|
4977
5354
|
};
|
4978
5355
|
|
4979
|
-
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
4980
|
-
var iconStyles = getSize(5);
|
4981
|
-
var buttonStyles = "min-bs-0 p-1";
|
4982
|
-
var tooltipProps = {
|
4983
|
-
side: "top",
|
4984
|
-
classNames: "z-10"
|
4985
|
-
};
|
4986
|
-
var ToolbarSeparator = () => /* @__PURE__ */ React3.createElement("div", {
|
4987
|
-
role: "separator",
|
4988
|
-
className: "grow"
|
4989
|
-
});
|
4990
|
-
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
4991
|
-
var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
4992
|
-
return /* @__PURE__ */ React3.createElement(ToolbarContextProvider, {
|
4993
|
-
onAction,
|
4994
|
-
state
|
4995
|
-
}, /* @__PURE__ */ React3.createElement(ElevationProvider, {
|
4996
|
-
elevation: "chrome"
|
4997
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
|
4998
|
-
classNames: [
|
4999
|
-
"p-1 is-full shrink-0 overflow-x-auto overflow-y-hidden",
|
5000
|
-
classNames
|
5001
|
-
],
|
5002
|
-
style: {
|
5003
|
-
contain: "layout"
|
5004
|
-
}
|
5005
|
-
}, children)));
|
5006
|
-
};
|
5007
|
-
var ToolbarToggleButton = ({ Icon: Icon2, children, ...props }) => {
|
5008
|
-
return /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
5009
|
-
asChild: true
|
5010
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, {
|
5011
|
-
variant: "ghost",
|
5012
|
-
...props,
|
5013
|
-
classNames: buttonStyles
|
5014
|
-
}, /* @__PURE__ */ React3.createElement(Icon2, {
|
5015
|
-
className: iconStyles
|
5016
|
-
}), /* @__PURE__ */ React3.createElement("span", {
|
5017
|
-
className: "sr-only"
|
5018
|
-
}, children))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
|
5019
|
-
};
|
5020
|
-
var ToolbarButton = ({ Icon: Icon2, children, ...props }) => {
|
5021
|
-
return /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
5022
|
-
asChild: true
|
5023
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
5024
|
-
variant: "ghost",
|
5025
|
-
...props,
|
5026
|
-
classNames: buttonStyles
|
5027
|
-
}, /* @__PURE__ */ React3.createElement(Icon2, {
|
5028
|
-
className: iconStyles
|
5029
|
-
}), /* @__PURE__ */ React3.createElement("span", {
|
5030
|
-
className: "sr-only"
|
5031
|
-
}, children))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
|
5032
|
-
};
|
5033
|
-
var HeadingIcons = {
|
5034
|
-
"0": Paragraph,
|
5035
|
-
"1": TextHOne,
|
5036
|
-
"2": TextHTwo,
|
5037
|
-
"3": TextHThree,
|
5038
|
-
"4": TextHFour,
|
5039
|
-
"5": TextHFive,
|
5040
|
-
"6": TextHSix
|
5041
|
-
};
|
5042
|
-
var MarkdownHeading = () => {
|
5043
|
-
const { t } = useTranslation(translationKey);
|
5044
|
-
const { onAction, state } = useToolbarContext("MarkdownFormatting");
|
5045
|
-
const blockType = state ? state.blockType : "paragraph";
|
5046
|
-
const header = blockType && /heading(\d)/.exec(blockType);
|
5047
|
-
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
5048
|
-
const HeadingIcon = HeadingIcons[value ?? "0"];
|
5049
|
-
const suppressNextTooltip = useRef(false);
|
5050
|
-
const [tooltipOpen, setTooltipOpen] = useState3(false);
|
5051
|
-
const [selectOpen, setSelectOpen] = useState3(false);
|
5052
|
-
return /* @__PURE__ */ React3.createElement(Tooltip.Root, {
|
5053
|
-
open: tooltipOpen,
|
5054
|
-
onOpenChange: (nextOpen) => {
|
5055
|
-
if (nextOpen && suppressNextTooltip.current) {
|
5056
|
-
suppressNextTooltip.current = false;
|
5057
|
-
return setTooltipOpen(false);
|
5058
|
-
} else {
|
5059
|
-
return setTooltipOpen(nextOpen);
|
5060
|
-
}
|
5061
|
-
}
|
5062
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
|
5063
|
-
open: selectOpen,
|
5064
|
-
onOpenChange: (nextOpen) => {
|
5065
|
-
if (!nextOpen) {
|
5066
|
-
suppressNextTooltip.current = true;
|
5067
|
-
}
|
5068
|
-
return setSelectOpen(nextOpen);
|
5069
|
-
}
|
5070
|
-
}, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
5071
|
-
asChild: true
|
5072
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
5073
|
-
asChild: true
|
5074
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
|
5075
|
-
asChild: true
|
5076
|
-
}, /* @__PURE__ */ React3.createElement(Button, {
|
5077
|
-
variant: "ghost",
|
5078
|
-
classNames: buttonStyles,
|
5079
|
-
disabled: value === null
|
5080
|
-
}, /* @__PURE__ */ React3.createElement("span", {
|
5081
|
-
className: "sr-only"
|
5082
|
-
}, t("heading label")), /* @__PURE__ */ React3.createElement(HeadingIcon, {
|
5083
|
-
className: iconStyles
|
5084
|
-
}), /* @__PURE__ */ React3.createElement(CaretDown, null))))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
|
5085
|
-
classNames: "is-min md:is-min",
|
5086
|
-
onCloseAutoFocus: (e) => e.preventDefault()
|
5087
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, Object.keys(HeadingIcons).map((level) => {
|
5088
|
-
const Icon2 = HeadingIcons[level];
|
5089
|
-
return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
|
5090
|
-
key: level,
|
5091
|
-
checked: value === level,
|
5092
|
-
onClick: () => onAction?.({
|
5093
|
-
type: "heading",
|
5094
|
-
data: level
|
5095
|
-
})
|
5096
|
-
}, /* @__PURE__ */ React3.createElement("span", {
|
5097
|
-
className: "sr-only"
|
5098
|
-
}, t("heading level label", {
|
5099
|
-
count: parseInt(level)
|
5100
|
-
})), /* @__PURE__ */ React3.createElement(Icon2, {
|
5101
|
-
className: iconStyles
|
5102
|
-
}), /* @__PURE__ */ React3.createElement(DropdownMenu.ItemIndicator, null, /* @__PURE__ */ React3.createElement(Check, null)));
|
5103
|
-
})), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
|
5104
|
-
};
|
5105
|
-
var markdownStyles = [
|
5106
|
-
{
|
5107
|
-
type: "strong",
|
5108
|
-
Icon: TextB,
|
5109
|
-
getState: (state) => !!state?.strong
|
5110
|
-
},
|
5111
|
-
{
|
5112
|
-
type: "emphasis",
|
5113
|
-
Icon: TextItalic,
|
5114
|
-
getState: (state) => !!state?.emphasis
|
5115
|
-
},
|
5116
|
-
{
|
5117
|
-
type: "strikethrough",
|
5118
|
-
Icon: TextStrikethrough,
|
5119
|
-
getState: (state) => !!state?.strikethrough
|
5120
|
-
},
|
5121
|
-
{
|
5122
|
-
type: "code",
|
5123
|
-
Icon: Code,
|
5124
|
-
getState: (state) => !!state?.code
|
5125
|
-
},
|
5126
|
-
{
|
5127
|
-
type: "link",
|
5128
|
-
Icon: Link,
|
5129
|
-
getState: (state) => !!state?.link
|
5130
|
-
}
|
5131
|
-
];
|
5132
|
-
var MarkdownStyles = () => {
|
5133
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
5134
|
-
const { t } = useTranslation(translationKey);
|
5135
|
-
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
5136
|
-
type: "multiple",
|
5137
|
-
value: markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)
|
5138
|
-
}, markdownStyles.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
5139
|
-
key: type,
|
5140
|
-
value: type,
|
5141
|
-
Icon: Icon2,
|
5142
|
-
disabled: state?.blockType === "codeblock",
|
5143
|
-
onClick: state ? () => onAction?.({
|
5144
|
-
type,
|
5145
|
-
data: !getState(state)
|
5146
|
-
}) : void 0
|
5147
|
-
}, t(`${type} label`))));
|
5148
|
-
};
|
5149
|
-
var markdownLists = [
|
5150
|
-
{
|
5151
|
-
type: "list-bullet",
|
5152
|
-
Icon: ListBullets,
|
5153
|
-
getState: (state) => state.listStyle === "bullet"
|
5154
|
-
},
|
5155
|
-
{
|
5156
|
-
type: "list-ordered",
|
5157
|
-
Icon: ListNumbers,
|
5158
|
-
getState: (state) => state.listStyle === "ordered"
|
5159
|
-
},
|
5160
|
-
{
|
5161
|
-
type: "list-task",
|
5162
|
-
Icon: ListChecks,
|
5163
|
-
getState: (state) => state.listStyle === "task"
|
5164
|
-
}
|
5165
|
-
];
|
5166
|
-
var MarkdownLists = () => {
|
5167
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
5168
|
-
const { t } = useTranslation(translationKey);
|
5169
|
-
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
5170
|
-
type: "single",
|
5171
|
-
value: state?.listStyle ? `list-${state.listStyle}` : ""
|
5172
|
-
}, markdownLists.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
5173
|
-
key: type,
|
5174
|
-
value: type,
|
5175
|
-
Icon: Icon2,
|
5176
|
-
onClick: state ? () => onAction?.({
|
5177
|
-
type,
|
5178
|
-
data: !getState(state)
|
5179
|
-
}) : void 0
|
5180
|
-
}, t(`${type} label`))));
|
5181
|
-
};
|
5182
|
-
var markdownBlocks = [
|
5183
|
-
{
|
5184
|
-
type: "blockquote",
|
5185
|
-
Icon: Quotes,
|
5186
|
-
getState: (state) => !!state?.blockQuote
|
5187
|
-
},
|
5188
|
-
{
|
5189
|
-
type: "codeblock",
|
5190
|
-
Icon: CodeBlock,
|
5191
|
-
getState: (state) => state.blockType === "codeblock"
|
5192
|
-
},
|
5193
|
-
{
|
5194
|
-
type: "table",
|
5195
|
-
Icon: Table2,
|
5196
|
-
getState: (state) => state.blockType === "tablecell",
|
5197
|
-
disabled: (state) => !state.blankLine
|
5198
|
-
}
|
5199
|
-
];
|
5200
|
-
var MarkdownBlocks = () => {
|
5201
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
5202
|
-
const { t } = useTranslation(translationKey);
|
5203
|
-
const value = markdownBlocks.find(({ getState }) => state && getState(state));
|
5204
|
-
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
5205
|
-
type: "single",
|
5206
|
-
value: value?.type ?? ""
|
5207
|
-
}, markdownBlocks.map(({ type, disabled, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
5208
|
-
key: type,
|
5209
|
-
value: type,
|
5210
|
-
Icon: Icon2,
|
5211
|
-
disabled: !state || disabled?.(state),
|
5212
|
-
onClick: state ? () => onAction?.({
|
5213
|
-
type,
|
5214
|
-
data: !getState(state)
|
5215
|
-
}) : void 0
|
5216
|
-
}, t(`${type} label`))));
|
5217
|
-
};
|
5218
|
-
var MarkdownStandard = () => /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(MarkdownHeading, null), /* @__PURE__ */ React3.createElement(MarkdownStyles, null), /* @__PURE__ */ React3.createElement(MarkdownLists, null), /* @__PURE__ */ React3.createElement(MarkdownBlocks, null));
|
5219
|
-
var MarkdownCustom = ({ onUpload } = {}) => {
|
5220
|
-
const { onAction } = useToolbarContext("MarkdownStyles");
|
5221
|
-
const { t } = useTranslation(translationKey);
|
5222
|
-
const { acceptedFiles, getInputProps, open } = useDropzone({
|
5223
|
-
multiple: false,
|
5224
|
-
noDrag: true,
|
5225
|
-
accept: {
|
5226
|
-
"image/*": [
|
5227
|
-
".jpg",
|
5228
|
-
".jpeg",
|
5229
|
-
".png",
|
5230
|
-
".gif"
|
5231
|
-
]
|
5232
|
-
}
|
5233
|
-
});
|
5234
|
-
useEffect2(() => {
|
5235
|
-
if (onUpload && acceptedFiles.length) {
|
5236
|
-
requestAnimationFrame(async () => {
|
5237
|
-
const f = acceptedFiles[0];
|
5238
|
-
const file = new File([
|
5239
|
-
f
|
5240
|
-
], f.name, {
|
5241
|
-
type: f.type,
|
5242
|
-
lastModified: f.lastModified
|
5243
|
-
});
|
5244
|
-
const info = await onUpload(file);
|
5245
|
-
if (info) {
|
5246
|
-
onAction?.({
|
5247
|
-
type: "image",
|
5248
|
-
data: info.url
|
5249
|
-
});
|
5250
|
-
}
|
5251
|
-
});
|
5252
|
-
}
|
5253
|
-
}, [
|
5254
|
-
acceptedFiles
|
5255
|
-
]);
|
5256
|
-
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("input", getInputProps()), /* @__PURE__ */ React3.createElement(ToolbarButton, {
|
5257
|
-
value: "image",
|
5258
|
-
Icon: Image,
|
5259
|
-
onClick: () => open()
|
5260
|
-
}, t("image label")));
|
5261
|
-
};
|
5262
|
-
var ViewModeIcons = {
|
5263
|
-
preview: PencilSimple,
|
5264
|
-
readonly: PencilSimpleSlash,
|
5265
|
-
source: MarkdownLogo
|
5266
|
-
};
|
5267
|
-
var MarkdownView = ({ mode }) => {
|
5268
|
-
const { t } = useTranslation(translationKey);
|
5269
|
-
const { onAction } = useToolbarContext("ViewMode");
|
5270
|
-
const ModeIcon = ViewModeIcons[mode ?? "preview"];
|
5271
|
-
const suppressNextTooltip = useRef(false);
|
5272
|
-
const [tooltipOpen, setTooltipOpen] = useState3(false);
|
5273
|
-
const [selectOpen, setSelectOpen] = useState3(false);
|
5274
|
-
return /* @__PURE__ */ React3.createElement(Tooltip.Root, {
|
5275
|
-
open: tooltipOpen,
|
5276
|
-
onOpenChange: (nextOpen) => {
|
5277
|
-
if (nextOpen && suppressNextTooltip.current) {
|
5278
|
-
suppressNextTooltip.current = false;
|
5279
|
-
return setTooltipOpen(false);
|
5280
|
-
} else {
|
5281
|
-
return setTooltipOpen(nextOpen);
|
5282
|
-
}
|
5283
|
-
}
|
5284
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
|
5285
|
-
open: selectOpen,
|
5286
|
-
onOpenChange: (nextOpen) => {
|
5287
|
-
if (!nextOpen) {
|
5288
|
-
suppressNextTooltip.current = true;
|
5289
|
-
}
|
5290
|
-
return setSelectOpen(nextOpen);
|
5291
|
-
}
|
5292
|
-
}, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
5293
|
-
asChild: true
|
5294
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
5295
|
-
asChild: true
|
5296
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
|
5297
|
-
asChild: true
|
5298
|
-
}, /* @__PURE__ */ React3.createElement(Button, {
|
5299
|
-
variant: "ghost",
|
5300
|
-
classNames: buttonStyles
|
5301
|
-
}, /* @__PURE__ */ React3.createElement("span", {
|
5302
|
-
className: "sr-only"
|
5303
|
-
}, t("mode label")), /* @__PURE__ */ React3.createElement(ModeIcon, {
|
5304
|
-
className: iconStyles
|
5305
|
-
}), /* @__PURE__ */ React3.createElement(CaretDown, null))))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
|
5306
|
-
classNames: "is-min md:is-min",
|
5307
|
-
onCloseAutoFocus: (e) => e.preventDefault()
|
5308
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
|
5309
|
-
const Icon2 = ViewModeIcons[value];
|
5310
|
-
return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
|
5311
|
-
key: value,
|
5312
|
-
checked: value === mode,
|
5313
|
-
onClick: () => onAction?.({
|
5314
|
-
type: "view-mode",
|
5315
|
-
data: value
|
5316
|
-
})
|
5317
|
-
}, /* @__PURE__ */ React3.createElement(Icon2, {
|
5318
|
-
className: iconStyles
|
5319
|
-
}), /* @__PURE__ */ React3.createElement("span", {
|
5320
|
-
className: "whitespace-nowrap grow"
|
5321
|
-
}, t(`${value} mode label`)), /* @__PURE__ */ React3.createElement(Check, {
|
5322
|
-
className: value === mode ? "visible" : "invisible"
|
5323
|
-
}));
|
5324
|
-
})), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, t("view mode label"), /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
|
5325
|
-
};
|
5326
|
-
var MarkdownActions = () => {
|
5327
|
-
const { onAction, state } = useToolbarContext("MarkdownActions");
|
5328
|
-
const { t } = useTranslation(translationKey);
|
5329
|
-
let commentToolTipKey = "comment label";
|
5330
|
-
if (state?.comment) {
|
5331
|
-
commentToolTipKey = "selection overlaps existing comment label";
|
5332
|
-
} else if (state?.selection === false) {
|
5333
|
-
commentToolTipKey = "select text to comment label";
|
5334
|
-
}
|
5335
|
-
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(ToolbarButton, {
|
5336
|
-
value: "search",
|
5337
|
-
Icon: MagnifyingGlass,
|
5338
|
-
onClick: () => onAction?.({
|
5339
|
-
type: "search"
|
5340
|
-
})
|
5341
|
-
}, t("search label")), /* @__PURE__ */ React3.createElement(ToolbarButton, {
|
5342
|
-
value: "comment",
|
5343
|
-
Icon: ChatText,
|
5344
|
-
"data-testid": "editor.toolbar.comment",
|
5345
|
-
onClick: () => onAction?.({
|
5346
|
-
type: "comment"
|
5347
|
-
}),
|
5348
|
-
disabled: !state || state.comment || !state.selection
|
5349
|
-
}, t(commentToolTipKey)));
|
5350
|
-
};
|
5351
|
-
var Toolbar = {
|
5352
|
-
Root: ToolbarRoot,
|
5353
|
-
Button: ToolbarToggleButton,
|
5354
|
-
Separator: ToolbarSeparator,
|
5355
|
-
View: MarkdownView,
|
5356
|
-
Markdown: MarkdownStandard,
|
5357
|
-
Custom: MarkdownCustom,
|
5358
|
-
Actions: MarkdownActions
|
5359
|
-
};
|
5360
|
-
|
5361
|
-
// packages/ui/react-ui-editor/src/defaults.ts
|
5362
|
-
import { EditorView as EditorView19 } from "@codemirror/view";
|
5363
|
-
import { mx as mx3 } from "@dxos/react-ui-theme";
|
5364
|
-
var margin = "!mt-[1rem]";
|
5365
|
-
var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
|
5366
|
-
var editorFullWidth = mx3(margin);
|
5367
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
5368
|
-
var editorGutter = EditorView19.theme({
|
5369
|
-
// Match margin from content.
|
5370
|
-
".cm-gutters": {
|
5371
|
-
marginTop: "16px",
|
5372
|
-
paddingRight: "1rem"
|
5373
|
-
}
|
5374
|
-
});
|
5375
|
-
var editorMonospace = EditorView19.theme({
|
5376
|
-
".cm-content": {
|
5377
|
-
fontFamily: fontMono
|
5378
|
-
}
|
5379
|
-
});
|
5380
|
-
|
5381
5356
|
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
5357
|
+
import { useCallback as useCallback2 } from "react";
|
5382
5358
|
var useActionHandler = (view) => {
|
5383
|
-
return (action) => view &&
|
5359
|
+
return useCallback2((action) => view && processEditorPayload(view, action.properties), [
|
5360
|
+
view
|
5361
|
+
]);
|
5384
5362
|
};
|
5385
5363
|
|
5386
5364
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
5387
5365
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
5388
5366
|
import { EditorView as EditorView20 } from "@codemirror/view";
|
5389
5367
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
5390
|
-
import { useCallback, useEffect as
|
5368
|
+
import { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo4, useRef, useState } from "react";
|
5391
5369
|
import { log as log7 } from "@dxos/log";
|
5392
5370
|
import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
5393
5371
|
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
5394
5372
|
var instanceCount = 0;
|
5395
5373
|
var useTextEditor = (props = {}, deps = []) => {
|
5396
|
-
const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } =
|
5397
|
-
const [instanceId] =
|
5398
|
-
const [view, setView] =
|
5399
|
-
const parentRef =
|
5400
|
-
|
5374
|
+
const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo4(() => getProviderValue(props), deps ?? []);
|
5375
|
+
const [instanceId] = useState(() => `text-editor-${++instanceCount}`);
|
5376
|
+
const [view, setView] = useState();
|
5377
|
+
const parentRef = useRef(null);
|
5378
|
+
useEffect2(() => {
|
5401
5379
|
let view2;
|
5402
5380
|
if (parentRef.current) {
|
5403
5381
|
log7("create", {
|
@@ -5471,7 +5449,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5471
5449
|
view2?.destroy();
|
5472
5450
|
};
|
5473
5451
|
}, deps);
|
5474
|
-
|
5452
|
+
useEffect2(() => {
|
5475
5453
|
if (view) {
|
5476
5454
|
if (scrollTo || selection) {
|
5477
5455
|
if (selection && selection.anchor > view.state.doc.length) {
|
@@ -5498,7 +5476,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5498
5476
|
scrollTo,
|
5499
5477
|
selection
|
5500
5478
|
]);
|
5501
|
-
|
5479
|
+
useEffect2(() => {
|
5502
5480
|
if (view && autoFocus) {
|
5503
5481
|
view.focus();
|
5504
5482
|
}
|
@@ -5512,7 +5490,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5512
5490
|
Escape: view?.state.facet(editorInputMode).noTabster
|
5513
5491
|
}
|
5514
5492
|
});
|
5515
|
-
const handleKeyUp =
|
5493
|
+
const handleKeyUp = useCallback3((event) => {
|
5516
5494
|
const { key, target, currentTarget } = event;
|
5517
5495
|
if (target === currentTarget) {
|
5518
5496
|
switch (key) {
|
@@ -5538,7 +5516,12 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5538
5516
|
};
|
5539
5517
|
export {
|
5540
5518
|
Cursor,
|
5519
|
+
EditorInputMode,
|
5541
5520
|
EditorInputModes,
|
5521
|
+
EditorState3 as EditorState,
|
5522
|
+
EditorToolbar,
|
5523
|
+
EditorView21 as EditorView,
|
5524
|
+
EditorViewMode,
|
5542
5525
|
EditorViewModes,
|
5543
5526
|
Inline,
|
5544
5527
|
InputModeExtensions,
|
@@ -5546,7 +5529,6 @@ export {
|
|
5546
5529
|
RemoteSelectionsDecorator,
|
5547
5530
|
SpaceAwarenessProvider,
|
5548
5531
|
TextKind,
|
5549
|
-
Toolbar,
|
5550
5532
|
addBlockquote,
|
5551
5533
|
addCodeblock,
|
5552
5534
|
addLink,
|
@@ -5565,8 +5547,10 @@ export {
|
|
5565
5547
|
commentsState,
|
5566
5548
|
convertTreeToJson,
|
5567
5549
|
createBasicExtensions,
|
5568
|
-
createComment,
|
5550
|
+
createComment2 as createComment,
|
5569
5551
|
createDataExtensions,
|
5552
|
+
createEditorAction,
|
5553
|
+
createEditorActionGroup,
|
5570
5554
|
createEditorStateStore,
|
5571
5555
|
createEditorStateTransaction,
|
5572
5556
|
createElement,
|
@@ -5605,7 +5589,7 @@ export {
|
|
5605
5589
|
mention,
|
5606
5590
|
overlap,
|
5607
5591
|
preventNewline,
|
5608
|
-
|
5592
|
+
processEditorPayload,
|
5609
5593
|
removeBlockquote,
|
5610
5594
|
removeCodeblock,
|
5611
5595
|
removeLink,
|
@@ -5621,6 +5605,8 @@ export {
|
|
5621
5605
|
setSelection,
|
5622
5606
|
setStyle,
|
5623
5607
|
singleValueFacet,
|
5608
|
+
stackItemContentEditorClassNames,
|
5609
|
+
stackItemContentToolbarClassNames,
|
5624
5610
|
table,
|
5625
5611
|
tags2 as tags,
|
5626
5612
|
textRange,
|
@@ -5638,9 +5624,9 @@ export {
|
|
5638
5624
|
useCommentClickListener,
|
5639
5625
|
useCommentState,
|
5640
5626
|
useComments,
|
5627
|
+
useEditorToolbarState,
|
5641
5628
|
useFormattingState,
|
5642
5629
|
useTextEditor,
|
5643
|
-
useToolbarContext,
|
5644
5630
|
wrapWithCatch
|
5645
5631
|
};
|
5646
5632
|
//# sourceMappingURL=index.mjs.map
|